Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript fetch handle both json and blob

Using javascript fetch and invoking a rest service that returns a blob if successful, otherwise returns an error message as json. How would this be handled in the fetch? The actual service is a asp.net web api implementation that returns a FileStreamResult (or FileContentResult) when successful, otherwise returns an error code with json containing the error message. Below is an example of what I'm trying to do:

fetch('flowers.jpg').then(function(response) {
  if(response.ok) {
    return response.blob();
  } else {
    return response.json();
}

}).then(function(myBlob) {  // here I would also like to function(jsonError)
  var objectURL = URL.createObjectURL(myBlob); 
  myImage.src = objectURL; 
}).catch(function(error) {
  console.log('There has been a problem with your fetch operation: ', error.message);
});
like image 848
Los Morales Avatar asked May 04 '18 11:05

Los Morales


People also ask

Does fetch return a json?

The simplest use of fetch() takes one argument — the path to the resource you want to fetch — and does not directly return the JSON response body but instead returns a promise that resolves with a Response object.

Why is fetch better than XMLHttpRequest?

It is an improvement over the XMLHttpRequest API. The main difference between Fetch and XMLHttpRequest is that the Fetch API uses Promises, hence avoiding callback hell . If you are new to promises then check out JavaScript Promises: an Introduction .

What is response json () in fetch?

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

How get json data from Fetch?

To get JSON from the server using the Fetch API, you can use the response. json() method. The response. json() method reads the data returned by the server and returns a promise that resolves with a JSON object.


2 Answers

Since you want to go down two fairly different paths, this is one of the relatively-rare situations where you probably want to nest handlers:

fetch('flowers.jpg').then(function(response) {
    if (response.ok) {
        return response.blob().then(function(myBlob) {
            var objectURL = URL.createObjectURL(myBlob);
            myImage.src = objectURL;
        });
    } else {
        return response.json().then(function(jsonError) {
            // ...
        });
    }
}).catch(function(error) {
    console.log('There has been a problem with your fetch operation: ', error.message);
});
like image 83
T.J. Crowder Avatar answered Oct 01 '22 05:10

T.J. Crowder


You can use nested then block to pass literally whatever you want to your next then handler. Sample:

fetch('flowers.jpg').then(function (response) {
    if (response.ok) {
        return response.blob()
            .then(function (myBlob) {
                return {
                    blob: myBlob
                };
            });
    } else {
        return response.json()
            .then(function (myJson) {
                return {
                    json: myJson
                };
            });
    }

}).then(function (myData) { 
    if(myData.blob){
        // Handle blob case
    }else{
        // Handle JSON case
    }
}).catch(function (error) {
    console.log('There has been a problem with your fetch operation: ', error.message);
});

Perhaps a more semantically accurate way of handling this is rejecting when there is an error.

fetch('flowers.jpg').then(function (response) {
    if (response.ok) {
        return response.blob();
    } else {
        return response.json()
            .then(function (myJson) {
                return Promise.reject(myJson);
            });
    }

}).then(function (myData) {
    // Handle blob case
}).catch(function (error) {
    //Handle JSON case
});
like image 32
Chirag Ravindra Avatar answered Oct 01 '22 04:10

Chirag Ravindra