Reputation: 25
What would be the best way if I have to top a loading. I have the following.
loadProducts() {
this.subscription = this._productService.getAll()
.subscribe(products => {
this.isLoading = false
this.products = products;
},
() => this.isLoading = false,
() => this.isLoading = false
);
}
this.isLoading = false in "next", "error" and "complete" Obviously it is to ensure that loading stops even when there is an error. There's a way to reduce this, let's say, something like attaching a callback or lambda to the subscribe and having it run in all cases
Upvotes: 0
Views: 1357
Reputation: 9357
You could do something like:
_cancel$ = new Subject<void>();
loadProducts() {
this.subscription = this._productService.getAll()
.pipe(takeUntil(this._cancel$))
.subscribe(products => (this.products = products),
() => this.isLoading = false,
() => this.isLoading = false
);
}
You can do this, for example:
<button (click)="loadProducts()">Load Products</button>
<button (click)="_cancel$.next()">Cancel Loading Products</button>
When _cancel$
emits, the ongoing subscription will be canceled as a consequence of the takeUntil
operator (it cancels the subscription when the observable passed as a parameter to it emits - complete function still runs).
There's no need to set isLoading
to false in the subscriber function because you're already doing it on the error function and on the complete function.
Upvotes: 0
Reputation: 1177
A common practice is to use RxJS operators for this case like finalize
or tap
and catchError
:
loadProducts() {
this.subscription = this._productService.getAll()
.pipe(
finalize(() => (this.isLoading = false)),
catchError(error => {
this.isLoading = false;
return throwError(error);
})
)
.subscribe(products => this.products = products);
}
Upvotes: 1