Skip to main content

Related Articles

How to share data between components in angular

 

sharing data between unrelated components 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.


<header>
  <div class="container">
    <a href="" class="logo">My flower shop</a>
  <span [style]="{'padding-left':'10px'}" >
      <input type="text" pInputText placeholder="Search" [(ngModel)]="searchText" />
  </span>
    <nav>
      <ul>
        <li><a href="" routerLink="/">Landing</a></li>
        <li><a href="" routerLink="/home">Home</a></li>
      </ul>
    </nav>
  </div>
</header>

<div class="container">
  <router-outlet></router-outlet>
</div>
  
Now once I refresh my browser, I can see below view which has the input text filed to enter search text.

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


data.service.spec.ts and data.service.ts in 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<string>;

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

   }
  
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<string>;

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

   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.

<div>Your search text is: {{searchText}}</div>

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.



  <header>
  <div class="container">
    <a href="" class="logo">My flower shop</a>
  <span [style]="{'padding-left':'10px'}" >
    
      <input type="text" pInputText placeholder="Search" (input)="updateSearchText()" [(ngModel)]="searchText" />
  </span>
    <nav>
      <ul>
        <li><a href="" routerLink="/">Landing</a></li>
        <li><a href="" routerLink="/home">Home</a></li>
      </ul>
    </nav>
  </div>
</header>

<div class="container">
  <router-outlet></router-outlet>
</div>

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.

how you can share data between parent child components

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.

Comments

Popular posts from this blog

The Power of ChatGPT and Whisper Models

A Deep Dive into Natural Language Processing Natural Language Processing (NLP) has seen a significant boost in recent years due to advancements in artificial intelligence and machine learning. Two models that have shown remarkable success in NLP are ChatGPT and Whisper. In this article, we will delve into the power of these models and their applications in the field of NLP. ChatGPT is a transformer-based language model developed by OpenAI that uses unsupervised learning to predict the next word in a sentence based on the context of previous words. ChatGPT is a generative model that is trained on large datasets of text, such as books and articles, and can be fine-tuned for specific tasks, such as question-answering or dialogue generation. ChatGPT is known for its ability to produce human-like text, making it an ideal tool for applications such as chatbots, content creation, and language translation. Whisper, on the other hand, is a paraphrasing model developed by Google that is based on...

Android: How to launch android emulator from command line or batch script?

Many Windows based Android developers are facing difficulties in running Android Studio on Windows machines due to lack of performance issues. But if you are developing mobile application using language like React Native you don’t actually need to work on Android Studio. But most of the time you have to use Android Emulators to test your application. If your windows machine does not have at least 16 GB of RAM you always face severe performance issue while running Android Emulators.   One solution to this issue is you can use your mobile phone to test react native application without running on Android Emulators. For that you only need to run Metro server on your PC and test application run on your mobile phone. But this method has drawbacks you have only one platform to test your application. If you want to test your application on multiple platforms you have to use several Emulators with different Android versions and architectures.   Another solution is without load ...

No More Database Programming Needed !

Are you tired in writing complex code for your database design? Want to be little relax? This article will help you to enjoy your job. In early days we had to write coding from the scratch to implement our database designs. Later people moved to database designing graphical tools. The latest trend of designing databases is use database navigation maps where you can visually feel your database design. This method is very useful if your database is little complex and you have lot of key constraints, referential integrity constraints, indexes and triggers etc. Using database navigation maps you can see either the entire database or part of it, how the tables are integrate each other, what are the keys you have defined for tables and references etc. Most importantly you don't need to write any single code or no need to remember complex SQL syntax.