7

Update

The issue seems to be that the map function is not run on a "failed" request. This means that if the API I'm talking to returns a 422 Validation Failed error (or other 4xx errors) Angular will treat this as a failure and cause the Observer to run the subscribed error callback, skipping the map function in the process.

Is it possible to force Angular to treat certain 4xx errors as successful requests, or force the map function to run even when an Observable returns an error?


I have the following code running in my Angular2 app:

import {Injectable} from "angular2/core";
import {Observable} from "rxjs/Rx";
import {Http, Headers, ResponseOptions, Response} from "angular2/http";
import 'rxjs/add/operator/map';

...

public login (email : string, password : string) {
    return this.http.post(_endPoint + '/auth/login/', JSON.stringify({
        email: email,
        password: password
    }), {
        headers: new Headers({
            'Content-Type': 'application/json'
        })
    })
    .map (res => {
        let data = res.json();
        console.log(data);
        return data;
    });
}

The code is executing fine, with the exception that the map function is not fired. I am not getting any errors, and have tried running the code both with and without the import 'rxjs/add/operator/map' with the same result. I have also tried a simpler map function .map (res => res.json());.

In both cases I expect the result returned in the .subscribe() function to be the JSON response, but instead I am getting the raw response.

Edit: Added a screenshot of the request data, and the response

Request details

Response:

[{"field":"email","message":"Email or password incorrect."},{"field":"password","message":"Email or password incorrect."}]

I've also tested it on a completely successful request (Status Code: 200) and the map function appears to be working fine. So I guess it only runs when a successful response is returned. Is there a way to get it to run regardless, or specify additional status codes that it should run on?

Tam
  • 761
  • 2
  • 11
  • 19
  • Could you provide us the content of your response? HTTP status code, headers and payload? Thanks! – Thierry Templier Jan 18 '16 at 13:37
  • Checkout http://stackoverflow.com/questions/34113750/angular-2s-http-service-not-exposing-map-and-other-rxjs-functions ... scroll down to see SystemJS configuration as mentioned by @MichaelOryl – lame_coder Jan 18 '16 at 13:43
  • @thierrytemplier I've a screenshot of the status, headers, & payload, and the response. I've also detailed what happens on a successful response. – Tam Jan 18 '16 at 13:53
  • @Tam thanks for the additiona details. I just provided you a solution based on the `catch` and `Observable.throw` methods. Hope it will help you ;-) – Thierry Templier Jan 18 '16 at 15:15

1 Answers1

7

As discussed with comments, the map method isn't called because the response contains a 422 status code, i.e. an error. So the catch method is directly called.

If you need to extract the JSON content corresponding to the error you could try something like that in your service:

getCompanies() {
  return this.http.get('https://angular2.apispark.net/v1/companies1/', {
    headers: headers
  }).map(res => res.json()).catch(err => Observable.throw(err.json());
}

Now in the component that calls the service, you will be able to subscribe. The second parameter will be called in your case with the JSON content of the response:

service.getCompanies().subscribe(
  data => console.log('data = '+data),
  err => console.log('err = '+JSON.stringify(err, null, 2)), // <---
  () => console.log('complete')
);

The printed content is:

err = {
  "code": 404,
  "description": "The server has not found anything matching the request URI",
  "reasonPhrase": "Not Found"
}

Hope it helps you, Thierry

Thierry Templier
  • 198,364
  • 44
  • 396
  • 360