Search code examples
ember.jsember-cli

How to get access to global variable in template?


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?


Solution

  • 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.");
    
           });
       }
    
    });