Search code examples
ember.jsember.js-2

How to access a routes model in Ember 2


I am having some trouble accessing my route's model inside my template. My model is created successfully as part of an action defined in my home controller:

actions: {
    createProject: function () {
        var project = this.store.createRecord('project', {
            name: 'Sample name'
        });
        var self = this;
        var promise = project.save();

        promise.then(function (response) {
            self.transitionToRoute('estimate', project);
        });
        promise.catch(function (errors) {
            console.log(errors);
        });
    }
}

The model's uuid is correctly serialized into the URL, with the URL inside my router.js being as follows:

  this.route('estimate');
  this.route('estimate', { path: '/estimate/:project_id' });

My estimate controller also correctly specifies the project dependency:

import Ember from 'ember';

export default Ember.Controller.extend({
    needs: ['project']
});

...and I define the model inside my routes/estimate.js as follows:

import Ember from 'ember';
import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin';

export default Ember.Route.extend(AuthenticatedRouteMixin, {
    // model: function(params) {
    //     return this.store.find('project', params.project_id);
    // },
    model(params) {
        return this.store.findRecord('project', params.project_id);
    }
});

Logging the output of this.store.findRecord('project', params.project_id) I get:

Class {__ember1458995391969: null, __ember_meta__: Meta}
__ember1458995391969
...

However when I try to access the project model inside my estimate handlebars template (using {{model.project.name}}), I get nothing (no errors, no output).

Anybody have any thoughts on this?


Solution

  • The return value of the model hook is bound to the model property of the controller, which binds into the template under the same name.

    You should write {{model.name}}, not {{model.project.name}}.

    Background

    Your model hook is returning an Ember Data promise object directly (which is normal). This means that model refers to your project object; there is no model.project property.

    Rendering {{model.project.name}} is like calling this.get('model.project.name') in your controller. Ember will return undefined for this path, even if model.project is undefined itself:

    > $E.get('model')
    < Class {store: Class, isLoaded: true, manager: Class, isUpdating: false, __ember1459002119210: "ember610"…}
    > $E.get('model.project')
    < undefined
    > $E.get('model.project.name')
    < undefined
    > $E.get('model.project.name.whatever')
    < undefined
    

    So there's no error in this case. And nothing shows up in the template, because null and undefined are rendered as blank strings.