Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Return a Observable from a Subscription with RxJS

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?

like image 835
Marcus Lind Avatar asked Apr 03 '18 12:04

Marcus Lind


People also ask

How do I return an Observable subscription?

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.

What does subscribe method return in Angular?

The subscribe() call returns a Subscription object that has an unsubscribe() method, which you call to stop receiving notifications.

What happens when you subscribe to an Observable?

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.

Is a subscription an Observable?

What is a Subscription? A Subscription is an object that represents a disposable resource, usually the execution of an Observable.


1 Answers

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)
}
like image 168
Marcus Lind Avatar answered Oct 12 '22 11:10

Marcus Lind