Ember gives you a powerful mechanism to get you application set up, as well as a way to nicely modularize any tricky things like setting up Websockets.

A Basic Application Initializer

In the last post, Handling Environment Data with Ember.js, we used an Initializer to read and cache environment variables that your App needs to know about. The basic form of an Initializer is:

1 Ember.Application.initializer({
2   name: "initializerName",
3 
4   initialize: function(container, application) {
5     ... your code ...
6   }
7 });

As you can see, you start off by giving your Initializer a name. This name allows you to later specify an order for the execution of your initializers by specifying either or both of before or after options, like so:

1 Ember.Application.initializer({
2   name: "configReader",
3   before: "websocketInit",
4 
5   initialize: function(container, application) {
6     ... your code ...
7   }
8 });
1 Ember.Application.initializer({
2   name: "websocketInit",
3   after: "configReader",
4 
5   initialize: function(container, application) {
6     ... your code ...
7   }
8 });

This will ensure that the configReader Initializer runs before the websocketInit Initializer.

Accessing the container and application instance

As you can see, the Initializer is passed both the container and application instance. This allows you to look up things you will most likely want to use, like the Adapter or Store:

adapter = container.lookup('adapter:application')
store = container.lookup('store:main')

You could also look up or set variables on your Application instance. For example, assuming you had run the environment config reader from the previous post first, in subsequent Initializers you can look up those environment variables:

userId = application.get('env.userId')

Asynchronous Initializers

If your Initializer performs a record lookup, then it’s vital that the Initializer simply doesn’t proceed allowing other Initializers to execute until that record lookup is fulfilled. You can tell Ember not to boot up the Application and start routing by utilizing the deferReadiness and advanceReadiness methods on the Application instanced passed to the Initializer.

For example, here’s an Initializer that looks up the Current user from the store, and injects it into the container, making it easily available in Routes and Controllers:

 1 Ember.Application.initializer({
 2   name: "currentUserLoader",
 3   after: "store",
 4 
 5   initialize: function(container, application) {
 6       // Wait until all of the following promises are resolved
 7       application.deferReadiness()
 8 
 9       container.lookup('store:main').find('user', 'current').then( function(user) {
10         // Register the `user:current` namespace
11         container.register('user:current', user, {instantiate: false, singleton: true});
12 
13         // Inject the namespace into controllers and routes
14         container.injection('route', 'currentUser', 'user:current');
15         container.injection('controller', 'currentUser', 'user:current');
16 
17         // Continue the Application boot process, allowing other Initializers to run
18         application.advanceReadiness();
19       });
20    }
21 });

Summary

Ember Application Initializers are a great tool for squaring away all of those pesky tasks that need to be performed to get your App ready to run. Here’s a list of possible use cases:

  • Injecting the current user into all Routes and Controllers
  • Setting up other Javascript libraries, like Socket.io
  • Reading environment configuration data
  • Setting a CSRF token to be used on all Ajax requests
  • Pre-loading records written to the HTML DOM into the Store for faster initial loading.

Are you already using Ember Application Initializers for something else not in the list above? Let me know in the comments below!