Reputation: 702
I am new on angular and stuck in a scenario where on page load I have to trigger 4 different APIs on ngOnit and have a click event on the same page while clicking on the event I want that it will stop all the previous calls, and makes new API call.
Code.
ngOnInit(): void {
this.getData('');
}
getData(data) {
const amount$ = this.service.getAmount(data).pipe(takeUntil(this.unSubscribe$));
const rate$ = this.service.getRate(data).pipe(takeUntil(this.unSubscribe$));
const applications$ = this.service.getApp(data).pipe(takeUntil(this.unSubscribe$));
const statistics$ = this.service.getStat(data).pipe(takeUntil(this.unSubscribe$));
applications$.subscribe(res => {
if (res.success) {
let d = res.dataSet;
}
}, (err) => {
})
------ and another three subscribe here
}
HTML
<button type="button" (click)="getData('abc')"
>Event</button>
'abc' is a dynamic string here that changes as per the need and then click on the button we pass the unique string in the getData function and on the basis of that string we hit a new API call on every click on the button but I want on every click it will stop all the previous APIs call and hit new one.
Upvotes: 0
Views: 552
Reputation: 17762
This is the typical scenario for switchMap
operator.
What I would do is something like this
// define a BehaviorSubject, i.e. a subject that emits a first vale as soon as
// it is subscribed. In this case it emits an empty string, as in the ngOnInit
start$ = new BehaviorSubject<string>('')
// then define the Observable that runs the APIs with start$ as its starting point
execute$ = start$.pipe(
// here you place switchMap which means: as soon as I get a value from
// upstream, I unsubscribe and preceding subscription and start a new subscription
switchMap(val => {
// with merge here I run all the 3 APIs concurrently
return merge(
this.amount$(val),
this.rate$(val),
this.applications$(val),
this.statistics(val)$
)
})
)
Each Observable that runs the API should be returned by a function that takes a string as input, so that we can use the value passed by the button click, like this
amount$ = (data) => { return this.service.getAmount(data); };
If this is an http call, you do not need the takeUntil
and the unsubscription logic, since the http client that Angular provides either emits once and then immediately complete or errors, so unsubscription is not needed.
Now in ngOnInit you create the one, and only one, subcription, like this
ngOnInit(): void {
this.execute$.subscribe(// whatever is necessary)
}
and in the handler of the button click event, you next
the start$
Subject, i.e. you make the start$
emit the string you want
<button type="button" (click)="start$.next('abc')"
>Event</button>
You can find an example (with http calls simulated) here.
Upvotes: 2