Senthe Senthe - 1 month ago 6
JSON Question

Using same model from store in a component used in all routes in Ember 2.8.0

My use case: application has a header that displays current user's name. This header is the same on all pages.

User data is loaded from JSON API into the Store when user logs in.

Now, how am I supposed to access this data from Store to use it on every page?





  1. One option is to pass it from routes:



{{app-header user=model}}


But then I would have to use the same model in all the routes and also would be unable to use any other? How can a (supposedly reusable) component expect from me to adjust every route to its data structure?





  1. The other option is that component always loads data from Store on its own, but this seems strongly unrecommended and actually very hard to do for me without any proper guide. I managed to discover service injection method (
    store: Ember.inject.service()
    in the component) but still can't get the component to properly display data from store in the template.



When I use:

name: () => {
return this.store.peekRecord('user', 1).get('name');
}


then
{{name}}
in template renders function definition, not what it returns.

When I use:

name: Ember.computed(() => {
return this.store.peekRecord('user', 1).get('name');
})


then
{{name}}
renders:
<!---->





Could you please explain what is a good way to do this? Is there some "master model" defined in
application.js
besides models from routes? Should I really pass the same data to component in every route? Any information or suggestions will be greatly appreciated.

Answer

You could try using a service (guide here).

// app/services/store.js
import DS from 'ember-data';
export default DS.Store.extend({});

// app/services/user-service.js
import Ember from 'ember';
export default Ember.Service.extend({
  store: Ember.inject.service(),
  user: Ember.computed(function() {
    return this.get('store').findRecord('user', ':id');
  })
});

Then, in all your other components, controllers, and routes, you can access the service.

// Inside a controller
export default Ember.controller.extend({
  userService: Ember.inject.service(),

  firstName: Ember.computed.alias('userService.user.firstName')
});

The first name, or even the user object itself is now available in you template.

{{userService.user.firstName}}
OR
{{firstName}}