Tuesday 19 September 2017

Angular: Share data between components using service file

Angular 2(+)Angular 4/5ServiceComponent

We can easily communicate with components by making a service file common. Inject the service file where ever you want and use it and this is the most preferred way. In the previous article I have explained about making a component reusable and sharing data between them. Now let us check by using a service file. Let us create two components first.

First Component


import { Component } from '@angular/core';
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title:String;
  list:any;
  constructor(){
    this.title = "Angular: Share data using service ";
    this.list = [
      {name:'Prashobh',age:'25'},
      {name:'Abraham',age:'35'},
      {name:'Anil',age:'40'},
      {name:'Sam',age:'40'},
      {name:'Philip',age:'40'},
      {name:'Bal',age:'40'},
      {name:'Anu',age:'20'}
    ]
  }
}


<div>
  <h3> {{title}}</h3>
  <app-list></app-list>
</div>

Second component


import { Component,Input } from '@angular/core';

@Component({
  selector: 'app-list',
  template:'<div>' 
    +'<button (click)="fetchDataFromService()">Get User Data</button>'
    +'<ul class="list" *ngIf="showList">'
     +'<li *ngFor="let l of list">{{l.name}}</li>'
    +'</ul>'
    +'</div>',
  styleUrls: ['./app.component.css']
})
export class Applist {
  list : any[];
  showList : boolean;
  constructor(){
    this.showList = false;
  }
  fetchDataFromService(){
     this.showList = true;
   }
}

We have created two basic component and output will looks like below image.

There is a list array in the first component, we are going to set that array into our service file and that can be used by any other component. Let us check how we can achieve that.

Service file


import { Injectable} from '@angular/core';  

@Injectable()
export class userDataService {  
   list:any;
   getUserData(){ 
      return this.list; 
   } 
   setUserData(data:any[]){
       this.list = data;
   }
}

Here we have two methods setUserData and getUserData. Using setUserData method we can set the data and that can be used anywhere by using getUserData method. You can use service file for making an API calls as well. I have written about the same using http and httpClient. httpClient is supported by Angular 4.3 version onwards. Now let us heck below updated components to get more idea.

Updated First Component


import { Component } from '@angular/core';
import {userDataService} from './userDataService'; 

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title:String;
  list:any;
  constructor(private _userData: userDataService){
    this.title = "Angular: Share data using service ";
    this.list = [
      {name:'Prashobh',age:'25'},
      {name:'Abraham',age:'35'},
      {name:'Anil',age:'40'},
      {name:'Sam',age:'40'},
      {name:'Philip',age:'40'},
      {name:'Bal',age:'40'},
      {name:'Anu',age:'20'}
    ]
    this._userData.setUserData(this.list);
   }
   
}

Here we are setting the data to our userDataService.

Updated Second component


import { Component,Input } from '@angular/core';
import {userDataService} from './userDataService'; 

@Component({
  selector: 'app-list',
  template:'<div>' 
    +'<button (click)="fetchDataFromService()">Get User Data</button>'
    +'<ul class="list" *ngIf="showList">'
      +'<li *ngFor="let l of list">{{l.name}}</li>'
    +'</ul>'
    +'</div>',
  styleUrls: ['./app.component.css']
})
export class Applist {
  list : any[];
  showList : boolean;
  constructor(private _userData: userDataService){
    this.showList = false;
  }
  fetchDataFromService(){
     this.showList = true;
     this.list = this._userData.getUserData();
   }
}

There are many other ways also there to share data between components, read here for more info: - 7 method to share data between angular components.

Sharing main module code as well below for better understanding.

Module


import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { DatePipe } from '@angular/common';
import { AppComponent } from './app.component';
import { Applist } from './app.listComponent';
import {userDataService} from './userDataService';

@NgModule({
  declarations: [
    AppComponent,Applist
  ],
  imports: [
    BrowserModule,
  ],
  providers: [userDataService],
  bootstrap: [AppComponent]
})
export class AppModule { }

We are done, click on the fetchDataFromService button and you can see the list. Here I have used angular (click) and *ngIf.

In this article we have discussed about sharing the data between components using a service file.

Angular 2(+)Angular 4/5ServiceComponent

Related Post

1. Angular: Create reusable component and pass data to component.

2. Date filtering and formatting using pipe in Angular 2.

8 comments :

  1. can you show me how do i communicate between two components in angular 2 which are in a following directory structure
    Layout => (some folder) => (component 1)

    => Parent(component) => (component 2)
    I am using shared service but stuck because I am getting data to the service but unable to fetch it in component 2 in a proper format. I have tried it with emitters, Subject and BehaviorSubject as well. A little help will be appreciated

    ReplyDelete
    Replies
    1. I am not sure what is the exact issue you are facing, but you no need to worry about folder structure. Just consider it is parent or child. If you are using a service then that also dosent matter. I have written some other method also to share data between components refer below link for that, it may help.

      http://www.angulartutorial.net/2017/12/share-data-between-angular-components.html

      Delete
    2. whenever i use the following method i get data but after refresh data get flused

      Delete
    3. Same. I am trying to fetch from an api with a click of a button and display on my second route/component. I click on the btn and get directed to my other route/component and see the call in the console but can't see it on the view because of the page refresh. I added a button and input field in the second component to make sure I have access to my service and I do.
      The goal is type zipcode in component 1 input field, fetch data and display it in sibling component 2 after being directed to that route.
      I am currently using a service that's fetching from a server.

      Delete
  2. data gets flushed after refresh

    ReplyDelete
  3. Yes i am having same issue while refreshing the page

    ReplyDelete
  4. This is such a great resource that you are providing and you give it away for free. I love seeing blog that understand the value of providing a quality resource for free. שרת וירטואלי

    ReplyDelete