Search code examples
ember.jsember-dataember-cli

Can you have deferred services with emberjs?


I am trying to load data using Ember CLI from a legacy API that seems to be unsuited to using Ember Data. This data will typically be loaded when the page loads and then reused in many places throughout the app. I have created a service 'legacy_data' for this:

import Ember from 'ember';

export default Ember.Service.extend({
  ready: null,
  legacy_data: null,

  init(){
   this.ready = Ember.$.ajax( ... ).done(function(legacy_data){
     this.set('legacy_data', legacy_data);
  }

  computed_attr: Ember.computed('legacy_data', function(){ ... },

  ...more functions and computed attributes
});

Because 'init' function does not seem to support returning a promise (Like the model hook on a route does), whenever I want to use this service, I have to do something like this:

injected_service.ready.then(function(legacy_data){
 ... use service
});

Which in practice means I end up with a whole bunch of additional promise handling in my codebase - It feels like I am swimming against the current on this one.

Is there a better way of doing this? Perhaps a lifecycle hook or a factory/initializer that supports deferred service initialization, so that I do not then have to worry about it everywhere else in my codebase? Do initializers support this? I have not seen it in any examples of it. Is there an alternative way of working around this issue? (Ember data must handle this same issue somehow, but I am new to the framework so am unsure)

Thank you for your help.


Solution

  • In Ember, Route's have hook such as beforeModel, model, afterModel. If you return promises from these hooks, promise handling are done by Ember.

    By the way, even if you are using Ember Data, calling store should be done by routes. If you access the store in your components, again you need to handle promises.

    But, you are asking a way to defer the application till the promise resolved. This can be achieved by application routes beforeModel hook. (I've needed this to retrieve the user permissions in my client app. Since I cannot place the permission promise handling in my all routes, I put it in my application route.) So, have a look at this twiddle.