I'm trying to update an RxJS Subject via a component's method . But it is not happening properly .
cricketData$ = new Subject<string>();
ngOnChanges() {
this.cricketData$
.asObservable()
.pipe(
tap(() =>
console.log(
'Triggering REST call for cricket tab with the year ',
this.year
)
),
take(1)
)
.subscribe();
this.cricketData$.next('sachin');
}
updateCricketData() {
this.cricketData$.next('dravid');
}
If I remove the take operator , subject is updated . But multiple service calls are triggered while selecting the values from dropdown . Is there any other operator / approach in RxJS using which I can achieve the below scenarios?
Please refer the below StackBlitz link . Thanks in advance .
Editor URL Stackblitz: EditorURL
App URL Stackblitz: AppURL
There are two issues.
First:
ngOnChanges
triggers multiple times, and every time you change the value you are adding a new pipe working parallelly.
take(1)
makes your previous pipe stop and only the recent pipe tab
is triggered.
ngOnInit(): void { // runs once
this.cricketData$
.asObservable()
.pipe( // runs on every next
tap(() =>
console.log(
'Triggering REST call for cricket tab with the year ',
this.year
)
)
)
.subscribe();
}
ngOnChanges() {
this.cricketData$.next('sachin'); // runs on every event on the page
}
Second issue: Do you really want to trigger this function on ngChange whenever there's an update on the page rather than just the dropdown, if the answer is only when there is a change in the dropdown then you can use a combination of Input set year(value: string)
export class CricketComponent implements OnChanges {
private _selectedYear: string;
@Input() set year(value: string) {
this._selectedYear = value;
this.cricketData$.next('sachin'); // will trigger with every drop down change
}
cricketData$ = new Subject<string>();
constructor() {}
ngOnInit(): void {
this.cricketData$
.asObservable()
.pipe(
tap((value) =>
console.log(
'Triggering REST call for cricket tab with the year ',
this._selectedYear,
value
)
)
)
.subscribe();
}
ngOnChanges() {}
updateCricketData() {
this.cricketData$.next('dravid');
}
}