Regression in async belongsTo handling in Ember 3.28?

After updating a very large app from 2.x to 3.28, I’ve encountered issues with async belongsTo relationships in our app. Specifically, we have Supplier and Client models, each of which extend from an Organization model. This all worked perfectly in the past. They are serialized separately and have separate endpoints in the API, but are one table in the backend and share many attributes.

The error we’re now seeing is the following:

-private.js:1038 Uncaught TypeError: Cannot read properties of undefined (reading 'kind')
    at notifyRelationship (-private.js:1038:1)
    at notifyChanges (-private.js:1024:1)
    at -private.js:1283:1
    at NotificationManager.notify (-private.js:6972:1)
    at InternalModel.notifyBelongsToChange (-private.js:6345:1)
    at -private.js:7456:1
    at Map.forEach (<anonymous>)
    at -private.js:7454:1
    at Map.forEach (<anonymous>)
    at RecordDataStoreWrapper._flushNotifications (-private.js:7450:1)

The issue is in notifyChanges function (see here: data/notify-changes.ts at 9889ebbd4eec162dba17bb00126ee71e49d04bce · emberjs/data · GitHub)

The record argument will typically be a record (e.g. Comment) and key will be a valid relationship (e.g. “author”), but when it gets to my Supplier record, it’s looking for a key called “organizations”. There’s no such relationship defined though and, again, this never happened prior to the upgrade.

I did notice if I remove the hasMany relationships (address & note) in Organization, the issue goes away. So I am guessing the mix up in notifyChanges results from the fact that Address and Note both belong-to Organization and it would be resolved by having a redundancy of those relationships on Supplier and Client and redundancy where I am using a single relationship (to Organization) currently for components using Address/Note.

If there’s a trick anyone knows to avoid this, that would be awesome. Sorry, this is probably a headache to follow…

Specifically, we have Supplier and Client models, each of which extend from an Organization model.

I did notice if I remove the hasMany relationships (address & note) in Organization, the issue goes away. So I am guessing the mix up in notifyChanges results from the fact that Address and Note both belong-to Organization

This sounds like the inverse relationship lookup is getting tripped up but maybe I’m not reading carefully enough. Let’s break it down…

So you have an organization model, and both supplier and client “are” organizations. An organization has many addresses, and an organization also has many notes. Address belongs to an organization, and note belongs to an organization. Therefore (by inheritance) a supplier will have many notes and a client will have many notes, and likewise with addresses. Does all that sound right?

A few follow up questions:

  • Are organizations ever created/queried by themselves or are they always interacted with in their subclasses e.g. client and supplier?
  • Do you actually use the hasMany relationships on organizations? (e.g. notes and addresses)
  • are the belongsTo(‘organization’) relationships polymorphic? Seems like they should be
1 Like

Thanks , @dknutsen, wow, I was totally unaware there was an explicit polymorphic option on relationships and in fact these relationships worked perfectly for four years without it until the upgrade! Adding them in seems to have completely resolved the problem. Can’t thank ya enough!

We have broader issues around async hasMany relationships and computed properties, but I will open a separate ticket for that! Thanks again for being so thorough and asking the right questions!

Brendan

historically lots of things could seem to work with polymorphism that were never supported, including the situation in which you don’t declare something explicitly polymorphic. Typically stuff was pretty broken under the hood in these cases but you may not notice it if your app avoids the features that broke.

1 Like