Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I initialize an Ember service at app boot without type injection?

Tags:

ember.js

Perhaps this is a little esoteric but I need some help.

My use case is a clock ticker. I want a service that upon init() will start a timer. (for example an AJAX polling service). I want this to start at app boot but I don't wish to inject it into every object type.

What I've tried:

  1. Writing a service and using Ember.inject.service() in the application controller.
  2. Use an initializer with app.register(…, MyService.create(), {instantiate: false}) without calling app.inject(…).
  3. Don't start the timer in the init() instead Ember.inject.service() it into the application route/controller and in its init() call this.get('myService').startTimer().

Here are some of the stumbling blocks I've run into:

  1. Services are lazy loaded and so the timer never starts because the application controller never performed a this.get('myService'). I could do that in the controller's init() but that felt like a code smell.
  2. Seems that the ember resolver will see the services/my-service.js file and auto register it. Performing an app.register() seems to register two instances and the two get confused.
  3. Like getting the lazy service in the application controller's init() this solution also felt like a code smell. But of all the solutions I've tried this works and is the least smelly of the three.

Is there any other alternatives?

like image 299
Sukima Avatar asked Jul 13 '16 01:07

Sukima


1 Answers

TL;DR Use an instance initializer

An instance initializer will have the needed lookup functions to fetch a service that the system auto registered and perform an action on it.

However, it may be more appropriate to save this initialization for a route or controller's init() because any ajax like thing here will still fall under Embers Loading state and run loop. While being performed in an instance initializer will degrade boot performance with no actual benefits.

If you still feel the initializer is the way to go here is a contrived example that is both Ember 1.13 and 2.0 compatible:

// app/instance-initializers/start-my-service.js
export function initialize(app) {
  const { container = app } = app;
  const myService = container.lookup('service:my-service');
  myService.startPolling();
}

export default {
  initialize
};

An example ember-twiddle.

like image 128
Sukima Avatar answered Nov 15 '22 11:11

Sukima