The model Hook

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.

4 min read Level 2/5 #ember#routes#data
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 beforeModelmodelafterModel.

Loading Substates →