1

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.

3
  • what is the return type of createNewRequest? Commented Jun 14, 2017 at 12:35
  • This is an Observable<Response> (basically a get or a post request). Commented Jun 14, 2017 at 12:37
  • 1
    the answer of @atomrc is what I had in mind Commented Jun 14, 2017 at 12:41

1 Answer 1

6

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

Sign up to request clarification or add additional context in comments.

8 Comments

I would recommend to use of as static method by importing it and use mergeMap instead of its alias (flatMap)
@Jota.Toledo humm indeed nice suggestion for the mergeMap :) I am not sure what you mean by using of as static? It is already static on Observable isn't it?
Yeah, but you can import the method itself by using import { of } from 'rxjs/observable/of';
Oh, I see. What is the exact benefits of using it this way? Is it for tree-shaking optimizations?
Exactly, bundle size related. Normally if you are concerned about the size of the scripts bundle you would import the rxjs operators individually. For example for mergeMap you would import the operator by using import 'rxjs/add/operator/mergeMap';
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.