Request Two Models together
Asked Answered
L

1

16

I have two models that are many to many. They're used on the first page of my app and I'm having trouble loading them.

Both models only have a handful of items (<200) and I'd like to just load both models completely in one findAll request each. But as the first model gets loaded, Ember starts fetching the missing data for the second model, item by item. If I try to just load the models separately, I get an error and have to set {async:true} for the hasMany attr. For some reason though, Ember isn't recognizing the json of the requests for the second model.

Is there anyway to fetch both models and wait till the both load before continuing?

Thanks.

Limnetic answered 12/10, 2013 at 7:48 Comment(0)
M
44

I'm guessing you are doing something along the lines of:

App.IndexRoute = Ember.Route.extend({
  model: function() {
    // Fetch the records of the first model 
    return this.store.find('post');
  },

  setupController: function(controller, model) {
    this._super(controller, model);
    this.store.find('comment').then(function(comments) {
      controller.set('comments', comments)
    });
  }
});

Any promise returned from the model hook of the route, will cause the router to pause transitioning until that promise is fulfilled. In the above case, the router will wait only for the posts request to resolve. Therefore we need to instruct the router to wait for both requests to complete.

Enter Ember.RSVP.all and Ember.RSVP.hash. These methods allow for merging multiple promises into one. They return a new promise that is fulfilled only when all of the individual promises are fulfilled. Here is how you do it with Ember.RSVP.hash:

App.IndexRoute = Ember.Route.extend({
  model: function() {
    var store = this.store;
    return Ember.RSVP.hash({
      posts: store.find('post'),
      comments: store.find('comment')
    });
  },

  setupController: function(controller, models) {
    var posts = models.posts;
    var comments = models.comments;

    controller.set('content', posts);
    controller.set('comments', comments);
  }
});
Mastoidectomy answered 12/10, 2013 at 9:38 Comment(4)
Thank you so much! That works great!! Sorry for not providing a code example. I'm actually using the models in two different render helpers, each with their own controller. For some reason, when it gets to those controllers, it's running the promise again? I thought that part of Ember-data is that it loads cache data? Should I be doing something differently?Limnetic
How does this work in the case of #link-to, where the model hook isn't called?Abutting
And this would not fly for models based on query params because refreshModel: true doesn't call the setupController hook. I also can't seem to figure out how to get params in the setupController method.Evvoia
you wouldn't need to call setupController if you access posts and comments through model: model.posts and model.comments.Ranking

© 2022 - 2024 — McMap. All rights reserved.