The Fetch API is used to make Ajax requests, such as calling the API or getting remote resources or HTML files from the server.
In the past, I have been very frank I prefer XHR to Fetch . I was wrong. Fetch is objectively better. It does everything I need with simpler grammar.
Let's see how it works.
Basic Fetch API syntax #
For today's article, we will use JSON placeholder To make a real API request.
Suppose you want to use https://jsonplaceholder.typicode.com/posts The endpoint gets the list of posts from the API. fetch() first, you pass it as a parameter to the method.
fetch('https://jsonplaceholder.typicode.com/posts');
Yesterday, we checked Promises in JavaScript.
The fetch() method returns a Promise. We can use then() and the processing API to respond to catch(). Let's log the response to the console.
fetch('https://jsonplaceholder.typicode.com/posts').then(function (response) { // The API call was successful! console.log('success!', response); }).catch(function (err) { // There was an error console.warn('Something went wrong.', err); });
If you look at the response in the console, you will notice jsonresponse Body is not available. This is something called a ReadableStream.
The Fetch API uses streams. To get our API data as JSON objects, we can use the native method of Fetch API: json() We will call it on our response object and return its value.
Then, we can use the actual response JSON in the chained then() method.
fetch('https://jsonplaceholder.typicode.com/posts').then(function (response) { // The API call was successful! return response.json(); }).then(function (data) { // This is the JSON from our response console.log(data); }).catch(function (err) { // There was an error console.warn('Something went wrong.', err); });
json() this is a demonstration of the Fetch method.
Handling errors using the Fetch API #
catch() because it returns a Promise, so the Fetch API uses this method to handle errors.
catch(), however, Promise will reject and trigger the method only if the request cannot be resolved. If the server responds, these then() methods will still run even if there is an Error 404 or 500.
For example, in the following request, I misspelled / posts as posts, resulting in 404
fetch('https://jsonplaceholder.typicode.com/postses').then(function (response) { // The API call was successful! return response.json(); }).then(function (data) { // This is the JSON from our response console.log(data); }).catch(function (err) { // There was an error console.warn('Something went wrong.', err); });
This is a demonstration. Please note that an empty JSON object is logged and our warning will not be displayed in the console.
How to correctly handle error codes using Fetch API #
To "fix" this behavior, we can use the ok attribute returned by Fetch Promise. response
If response If the OK attribute is true, we will return response json(). If not, we will return a rejected Promise object and pass in a response to trigger our catch() method.
fetch('https://jsonplaceholder.typicode.com/postses').then(function (response) { // The API call was successful! if (response.ok) { return response.json(); } else { return Promise.reject(response); } }).then(function (data) { // This is the JSON from our response console.log(data); }).catch(function (err) { // There was an error console.warn('Something went wrong.', err); });
This is a demonstration of Fetch requests with better error handling.
XHR does the same #
This kind of behavior really bothered me. This is one of my main arguments about why XHR is actually better.
But that's where I was completely, completely and stupidly wrong: XHR did the same.
onreadystatechange the XHR handler runs whether the response succeeds or fails. Before using it, you still need to check whether the response is in the range of 200 and 300.
// Setup our listener to process compeleted requests xhr.onreadystatechange = function () { // Only run if the request is complete if (xhr.readyState !== 4) return; // Process our return data if (xhr.status >= 200 && xhr.status < 300) { // What do when the request is successful console.log('success', JSON.parse(xhr.responseText)); } else { // What to do when the request has failed console.log('error', xhr); } };
Now, the Fetch API method is much cleaner.
Make other request types #
By default, the Fetch API makes a GET request. Suppose you want to POST a request to publish a new article through the API.
The fetch() method takes the second argument, which you can use to pass the option object. One of them is method.
fetch('https://jsonplaceholder.typicode.com/posts', { method: 'POST' }).then(function (response) { // The API call was successful! if (response.ok) { return response.json(); } else { return Promise.reject(response); } }).then(function (data) { // This is the JSON from our response console.log(data); }).catch(function (err) { // There was an error console.warn('Something went wrong.', err); });
For some types of requests, you may also need to pass data along with the request. You can do this using properties on the body option object.
This is usually a string, but it can also be if you are doing something like submitting a form using JavaScript A FormData object.
fetch('https://jsonplaceholder.typicode.com/posts', { method: 'POST', body: 'title=' + encodeURIComponent('My awesome new article') + '&body=' + encodeURIComponent('This is the text of my article') }).then(function (response) { // The API call was successful! if (response.ok) { return response.json(); } else { return Promise.reject(response); } }).then(function (data) { // This is the JSON from our response console.log(data); }).catch(function (err) { // There was an error console.warn('Something went wrong.', err); });
POST this is a request demonstration using the Fetch API.
Set header using Fetch API #
Another thing you may need to do is set the header and other properties for your request. This can also be done through the option object.
fetch('https://jsonplaceholder.typicode.com/posts', { method: 'POST', body: 'title=' + encodeURIComponent('My awesome new article') + '&body=' + encodeURIComponent('This is the text of my article'), headers: { 'Content-Type': 'application/json' }, referrer: 'no-referrer' }).then(function (response) { // The API call was successful! if (response.ok) { return response.json(); } else { return Promise.reject(response); } }).then(function (data) { // This is the JSON from our response console.log(data); }).catch(function (err) { // There was an error console.warn('Something went wrong.', err); });
You can View a complete list of options and values on the Mozilla Developer Network.
Browser compatibility #
The Fetch API is applicable to all modern browsers, including Edge, but does not support IE. It works for newer mobile browsers, but may not work for older mobile browsers (people usually don't update the operating system on their phones).
Should be used Include Fetch polyfill . It also requires a polyfill for Promises. Taylor Hakes This one is very good.
If you prefer to use polyfill.io , it contains Promises by default, but does not contain Fetch API. You should use the features flag to include it.
https://polyfill.io/v3/polyfill.min.js?features=default%2Cfetch