Async-Friendly Data Loading Per Route
The model Hook
model() returns the data for a route. Return a Promise and Ember waits; return a hash of records to load several things in parallel.
What you'll learn
- Return a single record, array, or Promise from model()
- Compose parallel loads with Promise.all or RSVP.hash
- Receive the resolved value as `@model` in templates
The model() hook is the place to load data for a route. It can return a value, a Promise, or a hash of Promises. Ember will not render the route’s template until the model has resolved.
Single Record
// app/routes/post.js
async model(params) {
return this.store.findRecord('post', params.post_id);
} In the template:
<h1>{{@model.title}}</h1>
<article>{{@model.body}}</article> Parallel Loads with Promise.all
async model(params) {
const [post, comments] = await Promise.all([
this.store.findRecord('post', params.post_id),
this.store.query('comment', { post: params.post_id }),
]);
return { post, comments };
} Then @model.post and @model.comments in the template.
RSVP.hash
import RSVP from 'rsvp';
async model(params) {
return RSVP.hash({
post: this.store.findRecord('post', params.post_id),
comments: this.store.query('comment', { post: params.post_id }),
related: this.store.query('post', { tag: 'related' }),
});
} RSVP.hash waits for every value in the object — handy when you have several independent fetches.
Refresh Data
@action
async refresh() {
await this.refresh(); // re-runs the model hook
} Calling this.refresh() from a route re-runs beforeModel → model → afterModel.