{{Quest 2}}: How to load multiple models on the same route?

Level: Intermediate

Abhilash L R
ember-titbits
2 min readJun 2, 2018

--

Supposing that you would need to load multiple data required for a page that is served by different API endpoints, then how do you approach fetching that data in the Ember route’s model hook?

For example, you have a form that requires meta information about countries while there is also a new form model that needs to be created while navigating to that route, now, we have 2 models — country and form. In order for the form to render the countries, let’s assume you are required to fetch that in the route. How do you go about it? Let’s see.

You want to be careful about whether or not returning multiple models in your model hook is appropriate. Ask yourself this simple question:

Does my route load dynamic data based on the url using a slug :id? i.e. this.resource('user-form', { path: ':id' });

If you answered yes

Do not attempt to load multiple models from the model hook in that route!!! The reason lies in the way Ember handles linking to routes. If you provide a model when linking to that route ({{link-to 'user-form.edit' model}}, transitionTo('user-form.edit', model)) it will skip the model hook and use the supplied model. This is probably problematic since you expected multiple models, but only one model would be delivered. Here's an alternative:

Do it in afterModel

If you need it to block the transition (like the model hook does) return a promise from the afterModel hook. You will need to manually keep track of the results from that hook and hook them up to your controller.

import Route from '@ember/routing/route';
import { get, set } from '@ember/object';
export default Route.extend({
model(params) {
return this.store.createRecord('user-form');
},
afterModel() {
return this.store.findAll('country').then((countries) => {
set(this, 'countries', countries);
}
},
setupController(controller, model) {
this._super(controller, model);
set(controller, 'countries', get(this, 'countries'));
}
});

If you answered no

Go ahead and return multiple models from the route’s model hook. You could use any combination inside the hash as RSVP will resolve the model hook only when all the objects are resolved.

import Route from '@ember/routing/route';export default Ember.Route.extend({
model() {
return Ember.RSVP.hash({
form: get(this, 'store').createRecord('user-form'),
countries: get(this, 'store').findAll('country')
};
}
});

This is a minor modification of what was posted on the same SO post and due credits to kingpin2k for posting such an elaborate answer.

PS: Clap if you liked, and don’t forget to follow me here: Abhilash L R or on Twitter @abhilashlr

--

--

Abhilash L R
ember-titbits

Loves to travel, writes about programming, photography, life lessons and sometimes cooking