Search code examples
ember.jsserviceember-data

Ember service undefined when injected in route


When I inject a service in my route and I try to access it into the model or even in beforeModel, the service is not undefined but when I try to access a value of the service, everything is undefined.

my service looks like this

import Service from '@ember/service';
import { inject as service } from '@ember/service';
import RSVP from 'rsvp';

export default Service.extend({
  session: service('session'),
  store: service(),

  load() {
    if (this.get('session.isAuthenticated')) {
      return this.get('store').queryRecord('user', { me: true }).then((user) => {
        this.set('user', user);
      });
    } else {
      return RSVP.resolve();
    }
  }
});

my route

import Route from '@ember/routing/route';
import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin';
import RSVP from 'rsvp';

import { inject as service } from '@ember/service';

export default Route.extend(AuthenticatedRouteMixin, {
  session: service('session'),
  currentUser: service('currentUser'),

});

And I want to access it in my template for example, {{currentUser.user.email}} but it only works when I do this in a component.


Solution

  • In order to access the currentUser service from the controller, inject the service into the controller. The route will need to invoke currentUser.load method first in order to populate the user property on the service. Note that you may only want to invoke currentUser.load method once, so I suggest doing that in the application route.

    route.js

    import Route from '@ember/routing/route';
    import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin';
    import RSVP from 'rsvp';
    
    import { inject as service } from '@ember/service';
    
    export default Route.extend(AuthenticatedRouteMixin, {
      session: service('session'),
      currentUser: service('currentUser'),
      model() {
        // This will load the user data before rendering
        // This can also be done in the beforeModel
        return this.get('currentUser').load();
      }
    });
    

    controller.js

    import Controller from '@ember/controller';
    import { inject as service } from '@ember/service;
    
    export default Controller.extend({
        currentUser: service()
    });
    

    template.hbs

    Email: {{currentUser.user.email}}