48

I wrote the following code in Angular 2:

this.http.request('http://thecatapi.com/api/images/get?format=html&results_per_page=10').
      subscribe((res: Response) => {
        console.log(res);
      })

When I print the response I get in console: enter image description here

I want to have access in the code to body field in the response. The 'body' field starts with an underscore, which means that it's a private field. When I change it to 'console.log(res._body)' I got an error.

Do you know any getter function that can help me here?

HDJEMAI
  • 7,766
  • 41
  • 60
  • 81
CrazySynthax
  • 9,442
  • 21
  • 70
  • 136
  • See here, https://stackoverflow.com/a/44622319/2803344, then you can use `res.json().results` to get the returned array. – Belter Jan 29 '18 at 08:20

11 Answers11

61

Both Request and Response extend Body. To get the contents, use the text() method.

this.http.request('http://thecatapi.com/api/images/get?format=html&results_per_page=10')
    .subscribe(response => console.log(response.text()))

That API was deprecated in Angular 5. The new HttpResponse<T> class instead has a .body() method. With a {responseType: 'text'} that should return a String.

OrangeDog
  • 30,151
  • 11
  • 105
  • 177
19

Here is an example to access response body using angular2 built in Response

import { Injectable } from '@angular/core';
import {Http,Response} from '@angular/http';

@Injectable()
export class SampleService {
  constructor(private http:Http) { }

  getData(){

    this.http.get(url)
   .map((res:Response) => (
       res.json() //Convert response to JSON
       //OR
       res.text() //Convert response to a string
   ))
   .subscribe(data => {console.log(data)})

  }
}
vishnu
  • 519
  • 7
  • 11
11

Here is an example of a get http call:

this.http
  .get('http://thecatapi.com/api/images/get?format=html&results_per_page=10')
  .map(this.extractData)
  .catch(this.handleError);

private extractData(res: Response) {
   let body = res.text();  // If response is a JSON use json()
   if (body) {
       return body.data || body;
    } else {
       return {};
    }
}

private handleError(error: any) {
   // In a real world app, we might use a remote logging infrastructure
   // We'd also dig deeper into the error to get a better message
   let errMsg = (error.message) ? error.message :
   error.status ? `${error.status} - ${error.statusText}` : 'Server error';
        console.error(errMsg); // log to console instead
        return Observable.throw(errMsg);
}

Note .get() instead of .request().

I wanted to also provide you extra extractData and handleError methods in case you need them and you don't have them.

rjdkolb
  • 8,217
  • 8
  • 57
  • 77
SrAxi
  • 18,577
  • 10
  • 42
  • 65
5

The response data are in JSON string form. The app must parse that string into JavaScript objects by calling response.json().

  this.http.request('http://thecatapi.com/api/images/get?format=html&results_per_page=10').
  .map(res => res.json())
  .subscribe(data => {
    console.log(data);
  })

https://angular.io/docs/ts/latest/guide/server-communication.html#!#extract-data

Dmitrij Kuba
  • 889
  • 8
  • 13
5

I had the same issue too and this worked for me try:

this.http.request('http://thecatapi.com/api/images/get?format=html&results_per_page=10').
  subscribe((res) => {
    let resSTR = JSON.stringify(res);
    let resJSON = JSON.parse(resStr);
    console.log(resJSON._body);
  })
A. Bahieddine
  • 67
  • 1
  • 1
4

Can't you just refer to the _body object directly? Apparently it doesn't return any errors if used this way.

this.http.get('https://thecatapi.com/api/images/get?format=html&results_per_page=10')
            .map(res => res)
            .subscribe(res => {
                this.data = res._body;
            });

Working plunker

kind user
  • 32,209
  • 6
  • 49
  • 63
  • 1
    Yes this is typically how I do it. I have even seen this way done in Pluralsight courses. My choice for the right answer. – Eric Bishard Sep 17 '17 at 09:18
  • Why would you use a map function which returns its argument? Wouldn't it accomplish exactly nothing? – Kevin Beal Aug 15 '18 at 22:53
4

Unfortunately, many of the answers simply indicate how to access the Response’s body as text. By default, the body of the response object is text, not an object as it is passed through a stream.

What you are looking for is the json() function of the Body object property on the Response object. MDN explains it much better than I:

The json() method of the Body mixin takes a Response stream and reads it to completion. It returns a promise that resolves with the result of parsing the body text as JSON.

response.json().then(function(data) { console.log(data);});

or using ES6:

response.json().then((data) => { console.log(data) });

Source: https://developer.mozilla.org/en-US/docs/Web/API/Body/json

This function returns a Promise by default, but note that this can be easily converted to an Observable for downstream consumption (stream pun not intended but works great).

Without invoking the json() function, the data, especially when attempting to access the _body property of the Response object, will be returned as text, which is obviously not what you want if you are looking for a deep object (as in an object with properties, or than can’t be simply converted into another objected).

Example of response objects

Arun Vinoth
  • 20,360
  • 14
  • 48
  • 135
pinky00106
  • 49
  • 1
  • 2
4
.subscribe(data => {   
            console.log(data);
            let body:string = JSON.parse(data['_body']);`
Remees M Syde
  • 2,691
  • 1
  • 17
  • 41
  • 4
    While this may answer the question, it is better to explain the essential parts of the answer and possibly what was the problem with OPs code. – pirho Dec 08 '17 at 13:55
0

Below one will work in all versions of Angular:

let body = JSON.parse(JSON.stringify(response)).body;
Chetan Purohit
  • 336
  • 1
  • 3
  • 16
-2

This is work for me 100% :

let data:Observable<any> = this.http.post(url, postData);
  data.subscribe((data) => {

  let d = data.json();
  console.log(d);
  console.log("result = " + d.result);
  console.log("url = " + d.image_url);      
  loader.dismiss();
});
casillas
  • 14,727
  • 15
  • 94
  • 183
-3

This should work. You can get body using response.json() if its a json response.

   this.http.request('http://thecatapi.com/api/images/get?format=html&results_per_page=10').
      subscribe((res: Response.json()) => {
        console.log(res);
      })
  • This will definitely not work. `Response` is a type, not a value. You can't call methods on it. – Kevin Beal Aug 15 '18 at 22:51
  • @ManPersonson it won't work, but that's not why. Every thing in JavaScript is a value. Every value has "methods" that can be called. `Response` is a function, not a type. – OrangeDog Nov 23 '18 at 10:12
  • @OrangeDog Yea, but not in this context. That's a type annotation. And it's deprecated, and he's trying to call an instance method on the class itself. In Typescript classes are types. – Kevin Beal Nov 23 '18 at 18:00