3

I want to check if my response has content in the body. I would have thought that res.totalBytes would do it, but it is always undefined.

this.http.get(this.url, this.options)
    .toPromise()
    .then( (res) => {
        console.log("totalBytes: "+res.totalBytes);//outputs 'totalBytes: undefined'
        console.log("res body: "+JSON.stringify(res.json()));//outputs a great big JSON object just as I would expect.
        });

What's the best way to check if the body is empty (ideally without relying on an exception being thrown), and why is totalBytes always undefined even when the body has a great big object in it?

WillyC
  • 3,917
  • 6
  • 35
  • 50
  • What does `console.log(typeof res);` print to your console? – eko Dec 07 '16 at 18:33
  • Just prints `object`. If I print out `res.status` I get `200`, and other than `totalBytes` it works like I'd expect a response to work. – WillyC Dec 07 '16 at 18:36
  • 1
    I don't think that `totalBytes` is implemented. Body can be obtained with `res.text()`. Is there a real reason for avoiding an exception? Promise/observable error handling is the most straightforward way to treat expected failures. – Estus Flask Dec 07 '16 at 19:06
  • I assumed that `text()` would throw an exception if the body was empty. I didn't experiment with it. If using exceptions is the accepted way to deal with expected errors that's fine. In other coding communities I have been a part of prior to JavaScript, using exceptions to deal with expected behaviour was frowned upon. I'm not passing judgement on that practice, just speaking about prior experience with communities for other languages. – WillyC Dec 07 '16 at 19:11
  • 1
    [It should be fine](https://github.com/angular/angular/blob/master/modules/%40angular/http/src/body.ts#L50-L52). This is a natural thing for observables/promises. An empty response is a particular case of invalid JSON response and thus it results in an exception from `JSON.parse`, I don't see why it should be treated differently. – Estus Flask Dec 07 '16 at 19:22

2 Answers2

1

for totalBytes or bytesLoaded, they are not standard properties, some time they will be undefined. So you can not use them to check whether body exists.

My current . solution is using result['_body'], like:

if (res['_body']) {
  json = res.json()
}

Although '_body' does not exist in the interface, but it exists in actual response. At least it works in my app.

Mavlarn
  • 3,807
  • 2
  • 37
  • 57
0

My Observable based solution: (Angular 11 for both currently)

(Be sure to have { observe: 'response' } as one of the this.options, for both solutions)

this.http.get(this.url, this.options)
.subscribe( (res) => {
  console.log(res.body['length']);
  if (res.body['length'] === 0) {
    console.log("Empty body!");
  }
} );

or Promise based solution:

this.http.get(this.url, this.options)
.toPromise()
.then( (res) => {
  console.log(res.body['length']);
  if (res.body['length'] === 0) {
    console.log("Empty body!");
  }
} );

Then just use it in a boolean of: res.body['length'] === 0

Image on when using dev tools to check object fields: https://i.stack.imgur.com/4n7gV.jpg (getting 'I am a teapot' error when I try to upload or use the image uploader, hence why I had to do this) - You can see that it contains a 'length' attribute under res.body .

Also tried using toPromise() as well earlier and converting in .json but learned that is not supported anymore and Observables return .json() directly after Angular 4.

I know this is an old question, but since I learned of this today thought to upload my Observable and Promise based solution. Hope this helps anyone in the future!

albes.k
  • 1
  • 1