Cédric Rémond
Cédric Rémond

Reputation: 1054

Angular2 and RxJS : Replace Observable Response by another Observable Response using Map

I am extending the Angular Http Object to handle a status code globally.

If this status is 201, the Response Object contains a new token for the authentication and, as it does not contains the results expected by the component which has subscribe to the request, it also contains everything to make this request again.

Basically, I follow these scheme (in the Http extending class) :

return request(url, options).map((res: Response) => {
    if (res.status === 201) {
        this._authService.updateAuth(res.token);

        const newRequest = this.createNewRequest(res); // returns an Observable<Response> created with the Http.get or Http.post method

        newRequest.map((res2: Response) => {
            return res2; // I want res2 to replace res through the first map, but there is a scope problem
        });
    } else {
        return res; // In non 201 case I keep the first response (res)
    }
});

The problem is that because of the scope I don't know how to return res2 in the first map so the response returned to the subscriber is the one it expects.

The request is successfully launched and the server returns 200 so everything is fine, but the subscriber doesn't receive the response back.

Upvotes: 1

Views: 986

Answers (1)

atomrc
atomrc

Reputation: 2583

You will need to flatten the stream in order to get the second response in the main stream. As the non 201 response will also be flatten, you will need to wrap it inside an observable.

Here is what your code will look like:

return request(url, options).mergeMap((res: Response) => {
    if (res.status === 201) { 
        return this.createNewRequest(res); // returning the new request's stream
    } else {
        return Rx.Observable.of(res); // wrapped inside an observable
    }
});

The important parts are the mergeMap instead of map and the wrapping in Rx.Observable.of

Upvotes: 6

Related Questions