Ember Simple Auth – How to Access the Current User in the Model Hook

Almost any serios web and mobile app has to deal with authentication at some point. Being a security matter this is not always easy to get done. Luckily, in Ember.js there is a great add-on for this. Ember Simple Auth is the standard solution for authorisation and authentication in Ember.

Apart from standard authorisation and authentication you can also extend this ESA’s functionality. For example have a current user property that you can use throughout your app.

Let’s assume that you need to access the current user in your route. You’ll likely need this so that you can retrieve a record or query your backend for some data based on it.

Make the current user available in your application via a service and inject it in your route. Here’s how you can do that, following the Ember Simple Auth documentation. There are 2 ways to request the current user:

Using a dedicated end point

// app/services/current-user.js
import Ember from 'ember';

const { inject: { service }, RSVP } = Ember;

export default Ember.Service.extend({
  session: service(),
  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();
    }
  }
});

// app/adapters/user.js
import ApplicationAdapter from './application';

export default ApplicationAdapter.extend({
  urlForQueryRecord(query) {
    if (query.me) {
      delete query.me;
      return `${this._super(...arguments)}/me`;
    }

    return this._super(...arguments);
  }
});

Loading the user with its id

// app/services/current-user.js
import Ember from 'ember';

const { inject: { service }, isEmpty, RSVP } = Ember;

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

  load() {
    let userId = this.get('session.data.authenticated.user_id');
    if (!isEmpty(userId)) {
      return this.get('store').findRecord('user', userId).then((user) => {
        this.set('user', user);
      });
    } else {
      return RSVP.resolve();
    }
  }
});

You now need to load the current user and populate the currentUser service user property. To do that you need to call the currentUser service load method.

// app/routes/application.js
import Ember from 'ember';
import ApplicationRouteMixin from 'ember-simple-auth/mixins/application-route-mixin';

const { service } = Ember.inject;

export default Ember.Route.extend(ApplicationRouteMixin, {
  currentUser: service(),

  beforeModel() {
    return this._loadCurrentUser();
  },

  sessionAuthenticated() {
    this._super(...arguments);
    this._loadCurrentUser();
  },

  _loadCurrentUser() {
    return this.get('currentUser').load().catch(() => this.get('session').invalidate());
  }
});

The current user in action

And now you have access to the current user via the currentUser service you created. Here’s an example of how you could use this. Given you have a list of bookings available at /bookings, you need a way to display all the bookings that belong to the current user at /bookings/me. Easy enough. Here’s how you can do this:

// app/routes/bookings/me.js
import Ember from 'ember';

const { inject: { service } } = Ember;

export default Ember.Route.extend({
  currentUser: service(),
   
  model() {
    let userId = this.get('currentUser.user.id');
    return this.store.query('booking', { user_id: userId });
  }
});

There are many use cases and needs for the current user and it’s not always this simple to solve your problem. But at least this gives you a starting point if you need to get more creative.

How to Validate Query Params in Ember.js – The Ember Way

We all want to make our application as future proof as possible. The result is that in many situations, some of us, avoid using Controllers at any cost. We end up with too much overhead and complexity and it becomes hard to maintain overtime. Here’s an article Dockyard wrote about the Controllers and what they’re good for. I recommend you give it a read if you want to follow some Ember best practices.


Let’s say you want to check if a query param is valid and if it isn’t you want to set it to a default value. Here are 2 simple ways to solve this in Ember.

Validation in the model hook

The only place you have access to the query params from within the route is the model hook. You can access the query param through the params hash.

// app/controllers/booking.js
export default Ember.Controller.extend({
  queryParams: ['booking'],
  booking: null
});
// app/routes/booking.js
export default Ember.Route.extend({
  model(params) {
    if (isPresent(params.booking)) {
      return this.store.findRecord('booking', params.booking);
    }
    this.transitionTo({ queryParams: { booking: 1 } });
  }
});

Here you check if the query param is present. If the condition is not met then call a transition to the current route with a default query param. And that’s it. Then the new transition is calling the model hook again, loading the model. Because this time the query param is present.

Validation in the setupController hook

You can also add some validation logic into the setupController hook. After all the query params are present on the Controller. You don’t have access to the params hash here but you know that the query params are properties on the Controller.

// app/controllers/booking.js
export default Ember.Controller.extend({
  queryParams: ['booking'],
  booking: null
});
// app/routes/booking.js
export default Ember.Route.extend({
  model(params) {
    if (isPresent(params.booking)) {
      return this.store.findRecord('booking', params.booking);
    }
  },

  setupController(controller, model) {
    this._super(controller, model);
    const booking = this.controller.get('booking');
    if (isEmpty(booking)) {
      this.transitionTo({ queryParams: { booking: 1 } });
    }
  }
});

In the setupController hook, you check if the booking property value is empty. If this condition is true, you’ll transition to the current route with a default query param value. The same we did in the model hook example. Of course you can do any type of validation depending on your app’s logic.

Ember Twiddle working demos

Here are both examples in action. Delete the query param value in the URL and hit enter. You should see it loading the default query param value as expected.

Validation in the model hook
Validation in the setupController hook