Reputation: 4102
Lets say I have two models, Book
and Chapter
.
App.Book = DS.Model.extend({
name: DS.attr(),
chapters: DS.hasMany('chapter', { async: true })
});
App.Chapter = DS.Model.extend({
name: DS.attr(),
book: DS.belongsTo('book')
});
I'm using the RESTAdapter
.
App.ApplicationAdapter = DS.RESTAdapter;
In the IndexRoute
let's say I want to fetch the first book (id = 1) and it's associated chapters. Since the hasMany
relationship is marked as async: true
, I want to fetch this association before the template is rendered.
App.IndexRoute = Ember.Route.extend({
model: function() {
return Ember.RSVP.hash({
book: this.store.find('book', 1)
}).then(function(hash) {
hash.chapters = hash.book.get('chapters');
return hash;
})
},
setupController: function(controller, model) {
controller.set('model', model.book);
}
});
My index template simply displays the book title, and iterates over its chapters.
<script type="text/x-handlebars" id="index">
<h3>Book: {{name}}</h3>
<ul>
{{#each chapters}}
<li>{{name}}</li>
{{/each}}
</ul>
</script>
When using mockjax, I setup the mock responses.
$.mockjax({
url: '/books/1',
responseText: {
book: {
id: 1,
name: 'Book 1',
chapters: [1, 2]
}
}
});
$.mockjax({
url: '/chapters?ids[]=1&ids[]=2',
responseText: {
chapters: [{
id: 1,
name: 'Chapter 1',
book_id: 1
}, {
id: 2,
name: 'Chapter 2',
book_id: 1
}]
}
});
Problem 1: According to the RESTAdapter docs, accessing book.get('chapters')
should issue a GET request to /chapters?ids[]=1&ids[]=2
. However, my console is showing two separate requests to /chapters/1
and /chapters/2
.
Problem 2: Furthermore, I believe the template is rendered before the chapters requests are happening because the template is rendered a second or two before I see the two requests to /chapters/1
and /chapters/2
. If I remove the call to hash.book.get('chapters')
from the route, the same problem happens. In other words, I don't think the route is sending the request, I think the template is.
Here is a jsbin. You'll notice it doesn't show any chapters because I haven't setup the two routes it's requesting (/chapters/1
and /chapters/2
).
Upvotes: 2
Views: 1369
Reputation: 1192
Cause for the first issue is simple: you used Dev(Canary) build of Ember Data which behaves differently to a beta build you can find on EmberJS site. It is bleeding edge so it's hard to tell if it's broken or if those are upcoming changes. If you want behavior consistent with the guide I would suggest using the latest beta build (Ember Data isn't marked as stable yet).
As for the second one: this is desired behavior since you're using async request along with Promises. This means, that you're immediately returning the result (there is no need for waiting for anything), however those results are empty until asynchronous requests are resolved.
You could wrap this behavior and (for example) inject a template only when your async routine is finished, however I would suggest rethinking it since based on personal experience it's not common pattern and most likely your app don't need it.
If you're are interested in how exactly those mechanisms work (you don't need this, it's only to satisfy potential curiosity on subject):
Upvotes: 1