Issue
Angular 9
I want to implement function to cancel api request when user click a button. I'm using "subscribe" so I thought "unsubscribe()" would work well, but not as I had expected.
this is a stackblitz sample code, which call/cancel api request, and response would be shown in console.
https://stackblitz.com/edit/angular-cancel-pending-http-requests-yavvkb
In this code, as below, I called "unsubscribe()" to cancel called request. Actually after calling "unsubscribe()", soon it reached to add(). but soon after, it received actual API response.
export class SearchService {
private foo: any = null;
constructor(private apiService: ApiService) { }
public getItemList() {
this.fetchData();
}
public cancel() {
if(this.foo != null) {
this.foo.unsubscribe();
console.log('unsubscribed');
}
}
private fetchData(){
const endPoint: string = 'https://www.mocky.io/v2/5c245ec630000072007a5f77?mocky-delay=2000ms';
this.foo = this.apiService.getData(endPoint).subscribe((resp)=>{
console.log(resp);
},(err)=>{
console.log(err);
}).add(() => {
this.foo = null;
console.log('complete');
});
}
}
output was
search clicked.
cancel clicked.
complete.
unsubscribed.
{status: true, statusMessage: "Items fetched successfully", data: Array[10]}.
After cancellation, I don't want to receive response because it's the purpose of "cancel". But I couldn't figure out how to do.
Thank you for your kind help, in advance.
Solution
You can use takeUntil()
from rxjs
together with a Subject
.
I've made an example stackblitz to show this approach: https://stackblitz.com/edit/angular-ivy-8vejbb?file=src/app/app.component.ts
import { Component } from '@angular/core';
import { Observable, Subject, takeUntil } from 'rxjs';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
private m_unsubscribe: Subject<void> = new Subject();
private m_fakeObsCallSource: Subject<void> = new Subject();
private fakeObsCall$: Observable<void> =
this.m_fakeObsCallSource.asObservable();
public sendDataToAPI(): void {
console.log('API call started');
this.fakeObsCall$.pipe(takeUntil(this.m_unsubscribe)).subscribe(
() => console.log('API Call returned data!'),
(error) => {
console.log('API Call ran into a problem!'),
() => {
console.log('API Call completed!');
};
}
);
setTimeout(() => {
this.m_fakeObsCallSource.next();
}, 3000);
}
public unsubscribe(): void {
console.log('Unsubscribed!');
this.m_unsubscribe.next();
}
}
Answered By - Mike S.
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.