-
-
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
beta-11 Wrapping relationships breaks quite a lot of app-side code #2418
Comments
@ginty I agree that writing content everywhere feels like a hack. What I usually do is set an alias for |
@ginty I think the way forward is to make certain things aware of promises, and 'unwrap' them where appropriate. There is already work completed in that direction, e.g. #2288, #2325 and #750. However, this won't solve all issues, and the ones you mention are tricky.
Bottom line is that promises are hard, but so are callbacks. I personally find promises more useful (though I understand if they feel confusing). A common theme in rich clients is that they work on a subset of data, with latency between the authoritative store (backend DB) and the client. In these cases, doing this async is necessary (in server-side code you can often resolve relationships etc. synchronously). Given these constraints, promises are really useful. @ginty Do you have any thoughts or suggestions on how the docs can be improved? It's easy to submit PRs to the docs, with ideas on improvements. For example: https://github.com/emberjs/website/blob/master/source/guides/models/finding-records.md [1] http://stackoverflow.com/questions/10539938/override-the-equivalence-comparison-in-javascript |
I was reading the CHANGELOG, and I couldn't find where this change was mentioned or what it meant. The most I could find was "Refactor relationship handling code". Is that it? Either way, it might be useful to mention. |
I've also been bitten by this behaviour, even knowing that the promise has settled and comparing some belongsTo relationship property with another model instance always fails, you must use The typical use case is in an observer where you want to update something conditionally. Its too easy to forget the '.content' as its not needed in other places. I have so much controller wrapping of model concerns and promise related constructs like this to deal with now that quite honestly I really am questioning where the payoff in Ember Data is above the adapter, serializer and identity map. |
The promise behaviour makes sense in the context of asynchronous relationships and in which case using relationship.then as described by @sandstrom above is reasonable. Similar to @ahacking I am preferring now not to use Ember Data for synchronous relationships when I can get away with it and have the API return embedded json blobs from which I can then just extract what I need using synchronous code. I guess this only works for cases where the relationship data is read only. |
@sandstrom Thanks for the reply above, certainly helpful. For me part of the problem was that my original code never treated these relationships like promises because I guess they never returned promises until now. I can certainly see the rationale for this. On the doc question the problem is that the model documentation does not mention that the relationships return promises at all and certainly examples like you show on how to deal with equality and similar logic on the relationship are required. I can help submit some doc patches here, but one problem for a user of ember data (rather than a core contributor) is that it is difficult to know what the end goal is. For example are synchronous relationships really meant to return promises or is that just a quirk of the current beta? |
@stefanpenner / @igorT I've think I recall hearing you mentioning refactoring the |
it is a real thing, after this current push on HTMLBars and streams, we plan on removing promise proxy all together in-favor of making the underlying RSVP system promise aware. |
Absolutely agree with the comments in this thread. I think a little bit of idiomatic documentation or a short guide on how to concretely handle promise behavior would go a long way. Just provide some examples and light commentary on the following:
I feel like I am running into the nuances of promises all the time and it often leads to a real and palpable feeling of frustration. I think this is mostly a documentation problem and just better understanding of how to code well functioning promise aware code. Hope it gets better. |
Great idea @eccegordo. Do you have any interest / bandwidth to take a stab at putting together some of that documentation? |
@bmac I would probably be down for helping some, if only to increase my own understanding of ember data internals. I don't always mean to be a complainer! 😄 The challenge is there is still a lot I need to understand about ED A few main interests I personally have:
I have started to look closer at the test cases to better understand ED. If I can make it through some of that and gain more insight I would be down to at least trying to add to some of the documentation effort. I fear I would still need some input and guidance on some of the finer points of ED. Is there a plan of record for future documentation? Let me see if I can organize my thoughts into a more coherent outline and get back to you. Would love to help if I can make the time. |
A few months ago, 100% of relationships in my app were synchronous, so I've been slowly trying to move towards async relationships as things get refactored, and I'm running into this same set of problems. I think I can say that ideally, application code should not need to care whether an object is a Accessing relationships on a record makes computed properties difficult, but there are usually workarounds. What makes promise wrappers especially difficult in my experience is passing models between different (conceptual) components in code. Every component (be it a controller, service, other model, or actual component) has its own API through properties, handlebars attributes, or method arguments that could expect a model instance. Simplistic example: {{! `model` was resolved in the model hook, so is a real DS.Model instance}}
Thing: {{thing-component model=model}}
{{! `model.parent` is an async belongsTo relationship, so is a DS.PromiseObject wrapper}}
Parent Thing: {{thing-component model=model.parent}} When some methods return promise wrappers and others model instances, it forces all APIs that expect models to deal with promise wrappers. This is simply not a reasonable expectation for developers given the amount of boilerplate ( The road to ED 1.0 post makes it sound like the solution is I think to get the rest of the way, what we need is the ability to do something like: export default Ember.Component.extend({
async isThingOtherThing() {
var thing = await this.get('thing');
var otherThing = await this.get('model.otherThing');
return otherThing === thing;
}.property('thing', 'model.otherThing')
}); But I honestly have no idea how feasible something like this is, given the current synchronous nature of CPs. This could be similar to what @stefanpenner mentioned above, since I doubt he actually meant he wants to make the promise system promise-aware 😉
|
@stefanpenner what is the status of this? is glimmer promise-aware? |
Not yet, but we would like to do so. |
Closing in favor of emberjs/ember.js#12825 |
Calls to retrieve a relation object, like user.get("address") for example are now wrapped in a DS.PromiseObject, however this is not a complete proxy for the real object.
Specifically the following broke in my app:
It's easy enough to fix once you know what to expect by calling .content everywhere on the promise object, i.e. replace "address" in all of the above with "address.content"
The following would help I think if the proxy cannot be made truly invisible:
Thanks!
The text was updated successfully, but these errors were encountered: