I currently have a service that do a HTTP request to an API to fetch data. There are some logic that I want to do to the observable from within the service, but I still want to also subscribe to the Observable in my Component so that I can return any errors to the Component and to the user.
Currently I do:
// service.ts
getData(): Observable<any> {
return this.http.get(url).pipe(catchError(this.handleError)
}
// component.ts
ngOnInit() {
this.service.getData().subscribe(res => {
// Do my logic that belong to the service.ts
// ...
// Do my logic that belongs in the component.ts
// ...
}, err => this.errors = err)
}
What I would like to do is to refactor this so that I handle the logic related to the subscription and the service.ts within the getData() method, and then return an Observable with the HTTP response and any errors to the Component so that I can continue doing things there.
What's the pattern to do this?
You can't return an observable from subscribe but if you use map instead of subscribe then an Observable is returned. Show activity on this post. Show activity on this post. Show activity on this post.
The subscribe() call returns a Subscription object that has an unsubscribe() method, which you call to stop receiving notifications.
It's good to know that when you subscribe to an observer, each call of subscribe() will trigger it's own independent execution for that given observer. Subscribe calls are not shared among multiple subscribers to the same observable. The code inside an observables represents the execution of the observables.
What is a Subscription? A Subscription is an object that represents a disposable resource, usually the execution of an Observable.
I feel like multiple of the patterns and solutions posted is "ugly" or does not follow the Observable
pattern (Like doing callbacks).
The cleanest, most "RxJS"-like solution I came up with was to wrap the service method's return value in a second Observable.
So the following:
// service.ts
getData(): Observable<any> {
return new Observable(subscriber => {
this.http.get(url)
.pipe(catchError(this.handleError)
.subscribe(res => {
// Do my service.ts logic.
// ...
subscriber.next(res)
subscriber.complete()
}, err => subscriber.error(err))
})
}
// component.ts
ngOnInit() {
this.service.getData().subscribe(res => {
// Do my component logic.
// ...
}, err => this.errors = err)
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With