1

I want to create global object with settings which I need to get from REST API. I need to make one request to REST API and get settings and after that I want to get access to these settings from any controllers and from any templates. What can you advice, what is the best practice for that problem?

Dmitro
  • 1,489
  • 4
  • 22
  • 40

2 Answers2

6

Concept

Good practice would be to use initializers. They allow injection of any data to routes, controllers or any other kind of object.

Lets take an example ( example from Ember.js official site )

1 . You have an Application and you have a logger service like this -

App = Ember.Application.extend();

App.Logger = Ember.Object.extend({
  log: function(m) {
    console.log(m);
  }
});

2 . Now you want to have this function log to available on all routes like this -

App.IndexRoute = Ember.Route.extend({
  activate: function(){
    // The logger property is injected into all routes
    this.logger.log('Entered the index route!');
  }
});

3. Tell ember to inject an object named Logger to all routes. Use initializer Like this

//I want to inject something
Ember.Application.initializer({

  //this dependency name is logger
  name: 'logger',

  //whenever ember runs
  initialize: function(container, application) {

    //register my logger object under a name
    application.register('logger:main', App.Logger);

    //and use this service 'logger' in all 'routes'
    application.inject('route', 'logger', 'logger:main');
  }
});

With this you can have your application level data / code available in all routes and controller.

Once you get your data in controller you can use it in templates pretty easily.

How to make API call with initializers ??

Initializer can be used to run after some other services has been resolved. Like in our case store. store is the object we need to make API call to server in good way (We can use $.getJSON() or anything else no issues)

Tell the initializers to run after store loaded

//I want to inject something but only after store resolved
Ember.Application.initializer({

  //this dependency name is logger
  name: 'logger',

  //wait for store object to be loaded, we need it to make API call
  after : 'store',


  //whenever ember runs
  initialize: function(container, application) {

      //grab the store object from container
      var store = container.lookup('store:main');

      //now you the store make that API call
      self.store.find('user',{current:true}).then(function(data){

            //we have the data we can inject it
            data = data.get('firstObject');
            container.lookup('controller:base').set('user', data);

            //user lookup success
            console.log("We have found an user. Yeah ember rocks.");

       });
   }

});
Sushant
  • 1,354
  • 1
  • 14
  • 31
  • Initializers are pretty cool - agreed. Not sure if they are the best tool for injecting **data** though... – Kalman Feb 25 '15 at 19:47
  • @KalmanHazins Yes, we can tell injection to run after `store` has been resolved. Then use `store` to make API call and inject data everywhere :) – Sushant Feb 25 '15 at 19:49
  • definitely could be done; I just wasn't sure if it's the best place for it. We need someone like @Oren to decide on this one ;) – Kalman Feb 25 '15 at 20:05
0

The settings object you are describing should probably live inside ApplicationRoute's model hook. You can then retrieve it in all your other models by saying modelFor('application') (see here). There is also a needs API (see here) that lets you share stuff between controllers in the application.

Kalman
  • 8,001
  • 1
  • 27
  • 45