How to share data between sibling components in Angular?
Let's say you have a component called First. Inside first component you have a button named increment.
There's another component second , inside this you have a variable named count=0 .
Now what interviewer wants if you click on increment button in first component , the count variable must increment in second component and reflect the same.
How you will achieve it???
import 'zone.js/dist/zone';
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
import { bootstrapApplication } from '@angular/platform-browser';
import { AppService } from './app.service'
@Component({
selector: 'my-first',
template: `
<h1>First</h1>
<button>Increment</button>
`,
standalone: true,
imports: [CommonModule],
})
export class First {
name = 'Angular';
}
@Component({
selector: 'my-second',
template: `
<h1>Second</h1>
<h2>{{count}}</h2>
`,
standalone: true,
imports: [CommonModule],
})
export class Second {
count: number = 0;
name = 'Angular';
}
@Component({
selector: 'my-app',
standalone: true,
imports: [First, Second, CommonModule],
providers: [AppService],
template: `
<h1>Hello from {{ name }}!</h1>
<a target="_blank" href="https://angular.io/start">
Learn more about Angular
</a>
<my-first></my-first>
<my-second></my-second>
`,
})
export class App {
name = 'Angular';
constructor(private appService: AppService) {
console.log(this.appService.getData())
}
}
bootstrapApplication(App);
Here's the code .
Link to Question -https://stackblitz.com/edit/stackblitz-starters-bxdzcr?file=src%2Fmain.ts
Answer :
There could be multiple approaches to achieve the same . But what i find easiest is through services.
Services in angular is used to establish a communication between the components who don't have parent child relationship and are completely different.
Here in above interview question first and second both are sibling components. Therefore you will use service here.
First you will create a service (i.e app.service.ts) here.
Second you will create two methods inside it, one is to get updated data (i.e getData()) , then the increment the count number that will be shared between two sibling component. We will create incrementData() method for this.
Now you will have to create a subject count , that you are going to subscribe to get updated value every time increment button is clicked.
Subjects are the kind of observable that gives you updated value consistently after every change. You can call next method to get updated value.
_That's how your code should look like _
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';
@Injectable()
export class AppService {
constructor() {}
count = new Subject<number>();
incrementData(count: number) {
this.count.next(count);
}
getData() {
return this.count;
}
}
- Now in first component you have to create a method that will call on every click of increment button.
Remember first step is initialise service inside constructor and then use it later to access service method
@Component({
selector: 'my-first',
template: `
<h1>First</h1>
<button (click)="incrementData()">Increment</button>
`,
standalone: true,
imports: [CommonModule],
})
export class First {
name = 'Angular';
count: number = 0;
constructor(private appService: AppService) {}
incrementData() {
this.appService.incrementData(this.count++);
}
}
- Now in Second Component you have subscribe to the subject created in service and update value
@Component({
selector: 'my-second',
template: `
<h1>Second</h1>
<h2>{{count}}</h2>
`,
standalone: true,
imports: [CommonModule],
})
export class Second {
constructor(private appService: AppService) {
this.appService.getData().subscribe((data) => {
console.log(data);
this.count = data;
});
}
count: number = 0;
name = 'Angular';
}
That's how you will do it .
Full code for answer is here :https://stackblitz.com/edit/stackblitz-starters-gv2eui?file=src%2Fmain.ts
Let me know if you have more ways to do it in comments.
Thanks for reading, do share if it helps you
Top comments (0)