{{Quest 2}}: How to load multiple models on the same route?
Level: Intermediate
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')
};
}
});
PS: Clap if you liked, and don’t forget to follow me here: Abhilash L R or on Twitter @abhilashlr