55

I load some binary data using

$http.post(url, data, { responseType: "arraybuffer" }).success(
            function (data) { /*  */ });

In case of an error, the server responds with an error JSON object like

{ "message" : "something went wrong!" }

Is there any way to get the error response in a different type than a success response?

$http.post(url, data, { responseType: "arraybuffer" })
  .success(function (data) { /*  */ })
  .error(function (data) { /* how to access data.message ??? */ })
3
  • You can return whatever error code/message you want from the server. "Something went wrong" seems like a 500. So in the serverside code once you catch the error don't return a 200 with an error message. For server errors it's 5xx and for client errors it's 4xx Commented May 5, 2015 at 12:13
  • @dcodesmith The status code is !== 200.I want to know what went wrong. Therefore I need to read the error message from the response. Commented May 5, 2015 at 12:15
  • @dcodesmith Status code doesn't matter for this question. The question is how to read the error response that is also an arraybuffer. Commented May 5, 2015 at 12:17

3 Answers 3

85

Edit: As @Paul LeBeau points out, my answer assumes that the response is ASCII encoded.

Basically you just need to decode the ArrayBuffer into a string and use JSON.parse().

var decodedString = String.fromCharCode.apply(null, new Uint8Array(data));
var obj = JSON.parse(decodedString);
var message = obj['message'];

I ran tests in IE11 & Chrome and this works just fine.

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

4 Comments

This gives me Unexpected token N in JSON at position
Have you looked at the decoded JSON string? Probably your API does not answer in proper JSON at all?
Looks like my issue got resolved after casting it as any like this ....apply(null, new Uint8Array(data) as any) (I'm using TypeScript)
Confirmed this is working fine.
29

@smkanadl's answer assumes that the response is ASCII. If your response is in another encoding, then that won't work.

Modern browsers (eg. FF and Chrome, but not IE yet) now support the TextDecoder interface that allows you to decode a string from an ArrayBuffer (via a DataView).

if ('TextDecoder' in window) {
  // Decode as UTF-8
  var dataView = new DataView(data);
  var decoder = new TextDecoder('utf8');
  var response = JSON.parse(decoder.decode(dataView));
} else {
  // Fallback decode as ASCII
  var decodedString = String.fromCharCode.apply(null, new Uint8Array(data));
  var response = JSON.parse(decodedString);
}

1 Comment

Definitely right. I tried your solution back then and found out it does not work in IE which was required.
1

Suppose in your service, you have a function you are using like, This is for Angular 2

someFunc (params) {
    let url = 'YOUR API LINK';
    let headers = new Headers();
    headers.append('Content-Type', 'application/json');
    headers.append('Authorization','Bearer ******');
    return this._http
            .post(url, JSON.stringify(body), { headers: headers})
            .map(res => res.json());    
}

Make sure when you return it it is res.json() and not res.json. Hope it helps, to anyone having this issue

Comments

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.