hswner
hswner

Reputation: 592

RxJS & Angular HttpClient: How to transform value asynchronously?

I want to apply an asynchronous transformation function on the value emitted by an observable.

@Injectable
export class ApiService{
    constructor(private http: HttpClient){}

    getSomething(url): Observable<any>{
        return this.http.get(url);
    }
}

In the code above, I want to apply a transformation function myFunc, which returns a promise, on the value emitted by this.http.get(url).

Normally I would use the map operator of RxJS, but since the transformation function returns a promise, I could not find a way to handle it.

For example, let my function be:

function myFunc(value){
    return new Promise((resolve, reject) => {
        // modify the value async

        resolve(modifiedValue);

        // ...
    });
}

Is there an appropriate way to handle this task? I think the following is not suitable, am I right?

return this.http.get(url).map(myFunc);

Any help will be much appreciated.

Note: I'm using RxJS 5.5.2

Upvotes: 2

Views: 2209

Answers (1)

rawkfist0215
rawkfist0215

Reputation: 1485

Use the mergeMap operator to take in the response value, perform some modification asynchronously via another Observable operation, and then return the modified value. This operator will merge the values emitted by HttpClient and your modifier Observable and return a single Observable that emits the mutated values.

EDIT: Including the Observable.fromPromise bit from @bygrace's comment for a more complete answer.

i.e.

EDIT: For RxJs v5.5+

import { pipe } from 'rxjs/util/pipe';
import { mergeMap } from 'rxjs/operators';


    @Injectable
    export class ApiService{
        constructor(private http: HttpClient){}

        getSomething(url): Observable<any>{
            return this.http.get(url).pipe( 
                                        mergeMap(myFunc) 
                                      );
        }

        private myFunc(x): Observable<any> {
            // do some asynchronous modification that returns an Observable
            return Observable.fromPromise(x);
        }
    }

Pre RxJs v5.5

@Injectable
export class ApiService{
    constructor(private http: HttpClient){}

    getSomething(url): Observable<any>{
        return this.http.get(url)
               .mergeMap(data => {
                   // do some asynchronous modification that returns an Observable
                   return Observable.fromPromise(data);
                });
    }
}

See: http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-mergeMap

Upvotes: 3

Related Questions