-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to tell if a relationship has been loaded #5629
Comments
@ryanto we have a great deal of information about the relationship state and whether we need to fire a request encapsulated in the From a private API perspective, you'll find that the relationship state class is attached to the reference. That should be enough to get you started and to figure out if there are some useful things to RFC. I suspect that proxying the method |
Cool! I had this working with some private APIs off of the reference, but it looks like this has changed since 3.1. Previously, I was relying on That made me realize that my code is pretty brittle and I need to do this in a blessed public API way. Given that the relationship state class isn't public, is there a way to figure this out with public APIs? Some decision tree based on reference values or ids? I've been playing around with a few things, but can't get anything to stick. If there's no public API for this sort of thing, which it sounds like that's the case, what's the best way for me to help push one through? Addon code that leads to an RFC? |
@ryanto I think you can test
should work |
Thanks, unfortunately that won't work for a let user = await store.findRecord('user', 1, { include: 'employer' });
let reference = user.belongsTo('employer');
// value is null, but employer has already been loaded. so we need to use reload here.
if (reference.value() === null) {
reference.load(); // no-ops
} else {
reference.reload();
} This however does work for |
I am surprised it works for |
I confirm, it seems that That aside, I agree that it would be very helpful to have a public |
can we have a listener which store operation is being used on the model? |
It works because
It's ambiguous for
So we need a way to disambiguate between these two cases. The introduction of a I spent some time trying to come up with a way to disambiguate the API of app/serializers/application.js export default DS.JSONAPISerializer.extend({
/** @inheritdoc */
extractRelationship(...args) {
const relationshipHash = this._super(...args);
// There is no public EmberData API that lets us probe whether a `belongsTo` relationship
// has been loaded (see https://github.com/emberjs/data/issues/5629), so we'll just throw
// a `loaded` flag in the meta hash for any `belongsTo` relationship included in the payload
// (i.e. where `data` is a resource identifier object). This flag can be consumed on
// `BelongsToReference` objects (e.g. `record.belongsTo('someRel').meta()`).
return Object.assign('data' in relationshipHash ? { meta: { loaded: true } } : {}, relationshipHash);
},
/** @inheritdoc */
normalizeFindBelongsToResponse(...args) {
// There is no public EmberData API that lets us probe whether a `belongsTo` relationship
// has been loaded (see https://github.com/emberjs/data/issues/5629), so we'll just throw
// a `loaded` flag in the top-level meta hash of any payload we got as a result of (re)loading
// a `belongsTo` relationship. This flag can be consumed on `BelongsToReference` objects
// (e.g. `record.belongsTo('someRel').meta()`).
return Object.assign({ meta: { loaded: true } }, this._super(...args));
},
}); app/utils/is-belong-to-relationship-loaded.js export default function isBelongToRelationshipLoaded(ref) {
// We'll consider a `belongsTo` relationship to have been loaded if it was fetched either
// directly (using a dedicated `Adapter.findBelongsTo()` request) or indirectly (through
// includes when fetching the owned resource), or when the inverse relationship has been
// loaded (i.e. `ref.value() !== null`).
return ref.meta()?.loaded || ref.value() !== null;
} Edit (2/11/2020)Turns out the above solution does not work in the case a I experimented a bit with
From the sound of it, Here is a quick way to get our hands on a app/serializers/application.js export const returnSnapshot = Symbol();
export default DS.JSONAPISerializer.extend({
serialize(snapshot, options) {
if (options[returnSnapshot]) {
return snapshot;
}
return this._super(...arguments);
},
}); app/utils/get-snapshot.js import { returnSnapshot } from 'my-app/serializers/application';
// Don't use this in a real app, this is bad
getSnapshot(record) {
return record.serialize({ [returnSnapshot]: true });
} However sadly: const someRecord = store.findRecord(...);
await someRecord.belongsTo('someRel').load(); // request returns `{ "data": null }`
getSnapshot(someRecord).belongsTo('someRel'); // undefined 😫 Note that the following works: const someRecord = store.findRecord(..., { include: 'someRel' });
getSnapshot(someRecord).belongsTo('someRel'); // null EmberData is at least beautifuly consistent in how broken it is. I am not goign to lie, I am getting a bit frustrated over this. I was... just trying to determine whether a given relationship has been loaded. |
@Herriau reach out on discord I'd love to pair for a little to poke at this |
Yearly check-in -- any progress on this issue? 🤔 Would also love to be able to check if my async relationship has been fetched or not 🙏 |
@joshkg yes, several of the linked issues have likely been resolved but need test PRs to confirm. They can be fixed fairly easily at this point if they aren't fixed already. |
I'm wondering if Ember Data has a way to know if a relationship has already been loaded.
I'm running into a situation where reference's
load
API changes based on wether or not the relationship has been loaded.For example...
I'd love to have a method to check if the relationship has been loaded in Ember Data's eyes. This would allow me to do something like...
The text was updated successfully, but these errors were encountered: