简体   繁体   中英

Observable Map function not running (Angular2, http)

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

请求详情

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?

As discussed with comments, the map method isn't called because the response contains a 422 status code, ie 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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM