Using services with a component

In Ember.js, a service is a singleton object that holds state. In other words, it can be shared throughout an Ember application and doesn't change. For example, session data, APIs that talk to a server, and WebSockets are good candidates for services.

In this recipe, we'll create and inject a service into a component.

Tip

Dependency injection

Services and dependency injection go hand in hand. Dependency Injection (DI) occurs when we take objects and inject them into other objects during instantiation. This means that we take a service and inject it into our routes, controllers, and components. This is an important framework concept and should not be overused. Having too many injected services would break the separation of concerns design principle.

How to do it...

  1. In a new application, generate these files:
    $ ember g service start
    $ ember g component comp-info
    $ ember g initializer init
    

    These files will be used to create our application. The service will hold a property and method that returns data.

  2. Begin by editing the start.js service:
    // app/services/start.js
    import Ember from 'ember';
    
    export default Ember.Service.extend({
        isOn: false,
        importantInfo(){
          return "Important Info is " + this.get('isOn');
        }
    });

    This is the services file. It has an isOn property and a method called importantInfo that returns a string. In this example, we want access to this information in our component, comp-info, so that it can be displayed.

  3. Edit the component comp-info.js file and add a new action that uses the start services information:
    // app/components/comp-info.js
    import Ember from 'ember';
    
    export default Ember.Component.extend({
        start: Ember.inject.service(),
        message: null,
        actions: {
          pressMe() {
            this.start.toggleProperty('isOn');
            this.set('message',this.start.importantInfo());
            console.log(this.start.isOn);
          }
        }
    
    });

    The most important thing in the component is the start property. We can inject the start service into the component using Ember.inject.service(). By convention, the name of the property must match the name of the service being injected. In our example, the start service will be injected.

    The pressMe action toggles the isOn property of the start service. We then set the text returned from the importantInfo method in the message property so that it can be displayed in the template.

  4. Add button to the template information for the component:
    // app/templates/components/comp-info.hbs
    <button {{action "pressMe"}}>push me</button><br>
    {{message}}

    In the component, all we are doing is adding an action to the button and displaying a message.

  5. Add the comp-info component to the application template file:
    <h2 id="title">Welcome to Ember</h2>
    
    {{outlet}}
    {{comp-info}}

    Now the template will display the component that was just created.

  6. Start the Ember server, and it will look as follows:
    How to do it...

    Pressing the button will toggle the isOn property. As you can see from this example, the service information was accessed by the component and displayed to the template.

  7. Create initializer that injects the service into all the components:
    // app/initializer/init
    export function initialize(app) {
        app.inject('component', 'start', 'service:start');
    }
    
    export default {
        name: 'init',
        initialize
    };

    Ember.js initializers are created when the application is started. It's a good place to preload data or set up the application state. The app argument, in the initialize function, is also known as Ember.Application. It serves as a registry for dependency declaration. Factories (classes) can be registered and injected into the application. The service:start is the key for the start service that we created earlier. Once a factory is registered, it can be injected anywhere in the application. As the start service has already been created, there is no need to register it.

    The app.inject takes three arguments. The first is the type to be injected. The second is the name of the service, start. Finally, the service:start factory is created.

  8. Update the component so that it no longer injects the start service as it's already available via the dependency injection:
    // app/components/comp-info.js
    …
    export default Ember.Component.extend({
        //start: Ember.inject.service(),
        message: null,
    …

    The start service is commented out so it's no longer available. The rest of the component remains the same as the service can still be retrieved using this.get('start'). This is due to the fact that we injected it into all the components in the initializer.

  9. Run the server again and the template loaded will remain the same with the same functionality.

How it works...

Services are long-lived Ember objects that can be used in different parts of your application. They are good to use with sessions, WebSockets, geolocation, logging, and more. They can be made available to the rest of the application using Ember.inject.service, which is a method that can retrieve services and make them available.

DI can be used to inject services into many different parts of the Ember application. Ember's architecture uses factories that are registered by Ember.Application. We can inject into all routes, components, and controllers using the Application.inject method.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset