Search code examples
javascriptember.jsdependency-injectionember-cli

Ember- 1.13 service not initialized in component


I have a clock service -clock.js

import Ember from 'ember';
var ONE_SECOND = 2000;

export default Ember.Object.extend({
  time : null,
  second : null,
  tick: function() {
    var clock = this;

    Ember.run.later(function () {
      var now = new moment();
      clock.setProperties({
        time : now,
        second : now.seconds()
      });
    }, ONE_SECOND);

  }.observes('second').on('init')
})

which I initialize as

export function initialize(container, application) {
  container.optionsForType('service:clock', { singleton: true });
  application.inject('route', 'clockService', 'service:clock');
  application.inject('controller', 'clockService', 'service:clock');
  application.inject('component', 'clockService', 'service:clock');
}

export default {
  name: 'clock-service',
  initialize: initialize
};

I use the clock ticker to compute elapsed time ( I am using moment.js).

timeElapsed : function(){
    var clock = this.get('clockService').get('time');
    var createdTime = new moment(this.get('request.createdAt'));
    var duration = moment.duration(clock.diff(createdTime));
    if(duration._data.hours > 0) return duration._data.hours+" hrs";
    if(duration._data.minutes > 0) return duration._data.minutes+" mins";
    if(duration._data.seconds > 0) return duration._data.seconds+" secs";
    return duration._data.seconds;
  }.property('request.createdAt','clockService.second')

Now the issue is the service is being injected in components but the properties are not set.


Solution

  • I was able to get it to run here, with some modifications:
    http://emberjs.jsbin.com/sexiqu/1/edit?html,js,output

    Please have a look at ClockServiceComponent.

    The only thing I am doing differently from your code is using a computed property with 'clock.time' as its dependent key, so the computed property will be lazy evaluated every one second.

    Ember.Application.initializer({
      name: 'registerClock',
    
      initialize: function(container, application) {
        application.register('clock:main', Ember.clockService);
      }
    });
    
    var ONE_SECOND = 1000;
    
    Ember.clockService = Ember.Service.extend({
      time : null,
      second : null,
      tick: function() {
        var self = this;
    
        Ember.run.later(function () {
          var now = new moment();
          self.setProperties({
            time: now,
            second: now.seconds()
          });
        }, ONE_SECOND);
      }.observes('second').on('init')
    });
    
    Ember.Application.initializer({
      name: 'injectClockService',
      initialize: function(container, application) {
        application.inject('controller', 'clock', 'clock:main');
        application.inject('route',      'clock', 'clock:main');
        application.inject('component',  'clock', 'clock:main');
      }
    });
    
    App = Ember.Application.create();
    App.Router.map(function() {
      // put your routes here
    });
    
    App.IndexRoute = Ember.Route.extend({});
    
    App.ClockServiceComponent = Ember.Component.extend({
      second: Ember.computed('clock.time', function() {
        return this.get('clock.second');
      })
    });