0
votes

Is there a standard way of handling errors when a 'findHasMany' call fails? Use case:

Model: App.User
{
DS.hasMany('comments', {'async': true});
}

Template

{{#each comment in comments}}
<p>{{comment.title}}</p>
{{/each}}

The issue is that when the lazy loading of comments fails, due to some server issue for example, I want to be able to respond to that error in the UI (by routing somewhere else, showing a popup about errors on the page, etc). At the moment the promise just rejects. I thought that Ember Data might have some hook on the ManyArray for cases like this, but it doesn't seem to, and the store seems to define precisely nothing as the action to carry out in such cases: https://github.com/emberjs/data/blob/v1.0.0-beta.8/packages/ember-data/lib/system/store.js#L1758 - the promise is given a 'resolve' method, but not a reject method.

My options seem to be either subclassing the store, and adding in some reject code there, or subclassing DS.PromiseArray and observing the 'isRejected' property. Any thoughts would be very welcome!

EDIT: This issue seems to boil down to the fact that, when handling models defined in a route, Ember and Ember Data work well together (you can catch rejecting promises in an error action) there is no similar structure for async requests directly through a template. One solution might be to have an observer in the controller that observes something like 'model.isError', but a failing hasMany relationship does not trigger an error on the owning model. I suppose instead I can do 'comments.isRejected', but again, I would have to code that in for every controller that has a model with a hasMany relationship, in other words, all of them, which doesn't seem very satisfactory. If models had an observable enumerable property (like "hasManyIsError": {comments: false, posts: true}) then it would be easy to observe any of them with 'hasManyIsError.length

1
I think you need to be a bit more specific about what you're trying to do. It sounds like you want to handle this in the route... in which case you can easily handle the case where it doesn't load the associations properly, but you can't do this generically unless you have some kind of route which works out what the associations are on the model and handles them that way...Julian Leviston

1 Answers

0
votes

Assuming a var called user that has been fetched, you'd do this:

var itWorked = function(comments) { return comments; }
var itFailed = function(error) { return error; }

user.get("comments").then(itWorked, itFailed);

async: true means it'll get using a promise... so you can use then... you can't do that on a relationship that doesn't specify async: true.

[edit] sorry I just realised it might not be obvous that whatever you put in the itFailed function will eval when the request for comments fails, and likewise inversely for itWorked... :)