Get Even More Visitors To Your Blog, Upgrade To A Business Listing >>

How to share data between components in angular


Today I am going to talk about how we can make interaction between two different components in angular.

There are two main approaches that we can follow.

1. If the two components are not relative, then you can use behavioral subjects to share data and trigger the event in one component, based on the value change in another component.

2. If the component is a child component of another component, then you can share data using @Input and @output directives

Today in this chapter we will discuss on the first approach.

How you can use Behavior subject to share between two components. 

The BehaviorSubject holds the value that needs to be shared with other components.

I will explain the concept using our Flower store app.

First, I will add PrimeNG text filed to the app.component.html file.

To add the text field you have to import it in app.module.ts and also in app.component.ts file


import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { LandingComponent } from './modules/landing/landing.component';
import { HomeComponent } from './modules/home/home.component';
import { CardModule } from 'primeng/card';
import {CheckboxModule} from 'primeng/checkbox';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import {InputTextModule} from 'primeng/inputtext';

@NgModule({
declarations: [
AppComponent,
LandingComponent,
HomeComponent
],
imports: [
BrowserModule,
AppRoutingModule,
CardModule,
CheckboxModule,
CommonModule,
FormsModule,
InputTextModule

],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Also need to import it inside app.component.ts. The ViewEncapsulation.None line need to add if you want to override PrimeNG styles inside your component.css file.


import { Component, ViewEncapsulation } from '@angular/core';
import {InputTextModule} from 'primeng/inputtext';

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'],
encapsulation: ViewEncapsulation.None

})
export class AppComponent {
title = 'my-flower-store';
searchText:string='';

In app.component.html file I have added the PrimeNG text filed as below.




My flower shop










Now once I refresh my browser, I can see below view which has the input text filed to enter search text.




Now what I am trying to do is I am going to display search text in my landing.component.html file.

Here the challenge I have is my search filed is in one component (app.component.html) and my flower cards in another component (landing.component.html). These two components don’t have any relationship.

How can I get the search text value from app.component.ts to landing.component.ts.

Here comes the angel Behavior Subject to support me.

Let me explain what you need to do to share the search text value using behavior subject concept.

First, I am going to generate the service class. To generate go inside the service folder and type below command.

>ng g s data

‘g’ and ‘s’ means generate service and then the ‘data’ is service name. This will create two files inside src/app/service folder




Inside the data service class, you can define the BehaviorSubject variable from string type to hold search text value.

Inside the constructor I have initialize it with empty string.

private searchText: BehaviorSubject;

constructor() {
this.searchText = new BehaviorSubject('');

}
Then I am going to add getters and setters as below.


public getUserName() {
return this.userName.asObservable();
}

public changeUserName(newUserName) {
this.userName.next(newUserName);

Now we have done with implementing shared data service class to handle behavioral subjects. Please see service code below.


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

@Injectable({
providedIn: 'root'
})

export class DataService {

private searchText: BehaviorSubject;

constructor() {
this.searchText = new BehaviorSubject('');
}

public getSearchText() {
return this.searchText.asObservable();
}

public setSearchText(searchText) {
this.searchText.next(searchText);
}
}

Now I can subscribe to this getSearchText() method from my landing.component.ts where I want to print new search text.

I need to inject my service class to the landing.component.ts file through the constructor.

Before inject I have imported the data.service.ts in my landing.component.ts file.


import { Component, OnInit, ViewEncapsulation } from '@angular/core';
import { flower } from '../../domain/flower';
import {CardModule} from 'primeng/card';
import {CheckboxModule} from 'primeng/checkbox';
import { DataService } from 'src/app/services/data.service';

@Component({
selector: 'app-landing',
templateUrl: './landing.component.html',
styleUrls: ['./landing.component.scss'],
encapsulation: ViewEncapsulation.None
})

export class LandingComponent implements OnInit {

myFlowerList:flower[]=[];
selectedFlowers: string[] = [];
checkedList:string[]=[];
searchText:string='';
constructor(private dataService:DataService) { }

ngOnInit() {
this.mySellingFlowers();
this.dataService.getSearchText().subscribe(response => {
this.printSearchtext(response);
})
}

printSearchtext(searchText){
this.searchText = searchText;
}

mySellingFlowers(){
let rose = new flower();
rose.name = "Rose";
rose.price = 100;
rose.availableQuantity = 1000;
rose.isChecked = false;
this. myFlowerList.push(rose);

let lily = new flower();
lily.name = "Lilly";
lily.price = 80;
lily.availableQuantity = 2000;
lily.isChecked = false;
this. myFlowerList.push(lily);

let tulip = new flower();
tulip.name = "Tulip";
tulip.price = 100;
tulip.availableQuantity = 2300;
lily.isChecked = false;

this. myFlowerList.push(tulip);

let carnation = new flower();
carnation.name = "Carnation";
carnation.price = 50;
carnation.availableQuantity = 1500;
lily.isChecked = false;

this. myFlowerList.push(carnation);

let gerbera = new flower();
gerbera.name = "Gerbera";
gerbera.price = 50;
gerbera.availableQuantity = 1500;
lily.isChecked = false;

this. myFlowerList.push(gerbera);

let orchid = new flower();
orchid.name = "Orchid";
orchid.price = 50;
orchid.availableQuantity = 1500;
lily.isChecked = false;

this. myFlowerList.push(orchid);

}

trackFlowers(index,flower){
return flower?flower.name:undefined
}
}

Once you subscribe to the behavior subject whenever it value change it will execute the printSearchtext() method.

Here I have print it in landing.component.html file as below.

Your search text is: {{searchText}}

When user type new search term we must update behavior subject.

I added below code in app.component.ts file to do that. Here also you need to inject your service class.

Then call setSearchText() method to update new values.

Here is the code in app.component.html. I have added input event where it triggers whenever user types something on the text filed.



 
    My flower shop
 
    
     
 
   
     
           
  • Landing
  •        
  • Home
  •      
       
     

     


    In app.component.ts I have defined the updateSearchText() method and call data service to update behavior subject.

    Import the data.service and inject it through constructor. This is called Dependency Injection in Angular. I will explain it in detail future.


    import { Component, ViewEncapsulation } from '@angular/core';
    import {InputTextModule} from 'primeng/inputtext';
    import { DataService } from './services/data.service';

    @Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.scss'],
    encapsulation: ViewEncapsulation.None

    })
    export class AppComponent {
    title = 'my-flower-store';
    searchText:string='';

    constructor(private dataService:DataService){

    }

    updateSearchText(){
    this.dataService.setSearchText(this.searchText);
    }
    }

    Now you can see the magic happens in your browser.


    Good Luck with learning concept of sharing data between unrelated components. Next chapter we will see how you can share data between parent child components.



    This post first appeared on Technical Discussions, please read the originial post: here

    Share the post

    How to share data between components in angular

    ×

    Subscribe to Technical Discussions

    Get updates delivered right to your inbox!

    Thank you for your subscription

    ×