Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can AngularJS set the responseType after a response has been received?

Tags:

angularjs

I have an Angular 1.x application that is expecting to receive a binary file download (pdf) using a $http.post() call. The problem is, I'd like to alternatively get a processing error message that's sent as json. I can do this with the config

headers: {
  'Accept': 'application/pdf, application/json'
}

The problem is I have have to set responseType: 'arraybuffer', otherwise the pdf binary is escaped (or altered such that it doesn't load). However, that prevents the json from being read or interpreted correctly.

How can I have both?

Edit: I'm going to try to clarify; perhaps my understanding is incorrect.

$http({
    method: 'POST',
    url: "/myresource",
    headers: {
        'Accept': 'application/pdf, application/json'
    },
    responseType: 'arraybuffer'
})
.then(
    function(response) {
        // handle pdf download via `new Blob([data])`
    }, function(response) {
        // pop up a message based on response.data
    }
)

In a scenario where I return a pdf data block and a http status of 200, the first function handles the response and prompts the user to save the file. However if the status is an error (422), the response.data is undefined. I assume this is because the responseType is preventing the json from being handled correctly.

If I remove the responseType line, the error data is correctly read, but when the pdf is saved, some of the file bytes aren't correct and it's effectively corrupted. I assume this is because the file is being encoded because javascript was expecting a string.

like image 822
end-user Avatar asked Dec 01 '16 20:12

end-user


People also ask

How do you modify the $HTTP request default Behaviour?

To add or overwrite these defaults, simply add or remove a property from these configuration objects. To add headers for an HTTP method other than POST or PUT, simply add a new object with the lowercased HTTP method name as the key, e.g. $httpProvider. defaults.

What is $HTTP in AngularJS?

$http is an AngularJS service for reading data from remote servers.

What is interceptor in AngularJS?

This interceptor is called when the $http receives the response from the server. This function receives a response object as a parameter return a response object or a promise. A response interceptor is used to modify the response data or adding a new set of values, calling another module or services call.

How to make a delete request in angular?

In the Angular client code when calling delete method you should set {responseType: ‘text’} so that it constructs a DELETE request that interprets the body as a text string and returns a string. For full Angular code please refer this post- Angular HttpClient to Communicate With Backend Service

What is the return type of delete method in angular?

As you can see method returns a String "Successfully deleted" if deletion is successful otherwise it returns "Error while deleting". In the Angular client code when calling delete method you should set {responseType: ‘text’} so that it constructs a DELETE request that interprets the body as a text string and returns a string.

Is it possible to type text in responsetype as JSON?

Actually, responseType only allows 'json' value. Typescript knows that. So writing 'text' as 'json' means "I give you 'text' value, but for type-checking, consider I gave you 'json'". So typescript won't complain. This only allows you to "lie" to typescript.

Why is my post method not receiving generic type arguments?

The error appears because the post method signature does not contain a generic type argument when responseType: 'text. post<T> (url: string, body: any | null, options?: { ... responseType?: 'json'; ... }): Observable<T>;


1 Answers

An XHR responseType property can not be changed after a response has been loaded. But an arraybuffer can be decoded and parsed depending on Content-Type:

 var config = {
    responseType: "arraybuffer",
    transformResponse: jsonBufferToObject,
  };

  function jsonBufferToObject (data, headersGetter, status) {
      var type = headersGetter("Content-Type");
      if (!type.startsWith("application/json")) {
        return data;
      };
      var decoder = new TextDecoder("utf-8");
      var domString = decoder.decode(data);
      var json = JSON.parse(domString);
      return json;
  };

  $http.get(url, config);

The above example sets the XHR to return an arraybuffer and uses a transformResponse function to detect Content-Type: application/json and convert it if necessary.

The DEMO on PLNKR

like image 186
georgeawg Avatar answered Sep 19 '22 19:09

georgeawg