Angular 2.0- Communication among components using Services

13 / May / 2016 by Giridhar Shukla 0 comments

In this article, we are going to discuss about how different components can share data using services. To understand services properly, I have developed a simple Angular 2 app in which components are sharing data with each other.

About Angular 2.0
Angular 2.0 is a new framework that helps in developing Single page JavaScript applications in a modular, maintainable and testable way. It is rewritten from Angular 1, following the best practices for future. The actual framework is written in TypeScript. TypeScript is just a superset of JavaScript. Any valid js code is a valid typescript. You need not to learn new a language. TypeScript provides many features of ECMA Script 6 that are supported by many browsers like classes, interfaces, access modifiers (public, private), IntelliSense and compile time checking. And of course, Angular 2 has a vast community support and is backed by Google.

Unlike Angular 1, it has 4 key components:

  • Components– Encapsulates the template, data and behaviour of the view.
  • Directives– To modify DOM elements and/or extend their behaviour.
  • Routers– To navigate in the application.
  • Services– Encapsulates the data calls to backend, business logic and anything not related to view.

In Angular 2 application development, there must be one root component that will be the parent of all the child components. It is just like the tree where all the components are individual and reusable.
Below is a sample component-
export class AppComponent { }
Yes, it is just a class that encapsulates some code. We exported the class so that other components can import it and use it accordingly. Similarly, Service is also a simple exported TypeScript class.

About the App
In this web app, there is a component biodata-list.component.ts that helps to list all the biodata that will be actually received from the service and the other component biodata-form.component.ts holds the form that will let users to post their data. We will also see how 2-way data binding works in Angular2 using [(ngModel)]. After submitting the form, the saved data automatically reflects in the above list which is controlled by different component. Actually the data is shared using service between these components.

PREREQUISITES
NodeJs version >=4
NPM version >=2

Follow the following steps to run this app:
1. npm install -g typescript
2. npm install -g typings
3. git clone
4. cd angular2-service
5. npm install
6. npm start
7. see your app in localhost:3000.
Note- If your changes don’t reflect to the browser, just restart the server.

Implementation Details
In this app, there are 3 components- app.component.ts, biodata-list.component.ts and biodata-form.component.ts. First we created model/contract for the form data using Interface in biodata.ts. The Typescript interface helps in defining abstractions or protocols. It is used to let angular know about what type of data and methods we are going to use. In the biodata abstraction, we can easily understand about the details of properties like data type, number and names of properties.

export interface biodata {
name: string,
phone: string,
qualification: string
}

Since we are not using any server to get data from database, so we will create a sample mock file mock-biodata-list.ts for the biodata form data. In this file we created a constant BiodataSet of type biodata which we just created above.

import {biodata} from './biodata';
export const BiodataSet: biodata[] = [ ];

Now its time to create our actual service biodata.service.ts. We will import Injectable function from angular 2 core library. When this Injectable function is used in any file as @Injectable() decorator, it tells angular that it is to be injected in different components or services. The components which get instance of the injectable service can use its methods for various purpose like data fetching/posting to server. Don’t forget to put parenthesis after the injectable decorator, otherwise it will lead to an error. In its class, all the methods are included to deal with the data fetching or posting. Mock data should also be imported here in service.

import {Injectable} from 'angular2/core';
import {BiodataSet} from './mock-biodata-list';

@Injectable()

export class biodataService {
getList() {
return Promise.resolve(BiodataSet);
}
saveNewData(data) {
BiodataSet.push(data);
}
}

How to use this service in component?
We will use this service in biodata-list.component.ts and biodata-form.component.ts components to share the data. In one component we used to get the list of all form data from backend and to save form data in other component.

The following things are required to use this service in biodata-list.component.ts:

Import biodataService class from service.
import {biodataService} from './biodata.service';

Pass the class in the providers metadata of component decorator.

providers: [biodataService]

Import the mock data list and data interface from respective files.

import {BiodataSet} from './mock-biodata-list';
import {biodata} from './biodata';

Create a variable AllBiodata of type biodata that we just imported from biodata.ts.

public AllBiodata: biodata[];

In its constructor method, define a private variable _biodataService of type biodataService, so that Angular2 knows what type of object is needed here.

constructor(private _biodataService: biodataService) {}

Then define a method in this component that will fetch the data list from the promise that is returned by the service method and set the variable AllBiodata to the data object returned by the service but this method will not get executed automatically. We can call this in our constructor but it is not good practice and it might lead to bad performance.

getAllBiodata() {
this._biodataService.getList().then((BiodataSet: biodata[])=>this.AllBiodata = BiodataSet);
}

To overcome above problem, we will Angular 2 Lifecycle hooks. During the initiation phase of the component, we used OnInit protocol from angular2 core library. We have to implement this protocol in the component class.

export class BiodataListComponent implements OnInit {...

After implementing this protocol, it is necessary to define ngOnInit method otherwise it will lead to error. Now in this method, we will call the getAllBiodata() method to execute it during the initiation of the component.

import {OnInit} from 'angular2/core';
..
...
ngOnInit() {
this.getAllBiodata();
}

Similarly, we will use this service in other components where data are to be shared.

import {Component} from 'angular2/core';
import {NgForm} from 'angular2/common';
import {biodataService} from './biodata.service';
import {BiodataSet} from './mock-biodata-list';
import {biodata} from './biodata';

@Component({
selector:’biodata-form’,
template: `
All html code goes here
`
})

export class biodataFormComponent {
….
constructor(private _biodataService: biodataService) {}
….
}

Now go ahead and run the actual app in your browser and see the real code.

I hope this post helps clear up the concepts of services in Angular 2.

Read Further on AngularJS Series

FOUND THIS USEFUL? SHARE IT

Leave a Reply

Your email address will not be published. Required fields are marked *