AJAX In It’s Modern Form — The Fetch API.

AJAX gets its hype from its ability to make a client-side network request from a server, and update the DOM without reloading the page. This gives us the ability to do things like load a user’s information, submit orders, and generally allow a user to manipulate their own data, all in a fast and efficient way.

AJAX stands for Asynchronous Javascript and XML. Today, it’s an umbrella term for HTTP network requests, although it used to refer specifically to XMLHttpRequests. Since IE5 was released in 1998 it’s been possible to make XMLHttpRequests which were almost always implemented with the help of a library like jQuery. You’ll still see some XMLHttpRequests in old code with methods likejQuery.ajax(), jQuery.get(), and jQuery.post(), however today we use the Fetch API in Javascript.

Fetch — making modern requests

Fetch makes sending an Http request simpler than ever! Here’s the basic format to the left. The simplest fetch is a GET request and takes in one argument, the URL. After the fetch is sent, it waits to receive a response from the server or a promise. We use .then to capture the promise. We can use multiple .then’s in a row, each one giving the next access to its result. This is called promise chaining.

Let’s contextualize our example. Let’s say the backend is set up to receive a GET request to “…/users” and render a response in JSON of all the user's names listed in the database. The first .then gives us a JSON object of the result, while the second .then passes the result to the function handleResult().

Sending request headers in a fetch request
Sending request headers in a fetch request

Sending metadata with a Fetch

Let’s say we have a user that wants to create an account. Here, we need to send information to the server and tell it to save the information as a new user. For these fetches, we need to include a second argument, the request headers object. Take a look at the example.

The method tells the controller what kind of CRUD action to take, in this case, we are making a POST request so it is sent to the create action.

The headers give the backend information about the content that we send over in the body. For example, if a bearer token was needed to make this post request we would include the header, "Authorization": `Bearer ${token}`.

The body is where the information we are sending lives. In this case, we are sending over a JSON object with the username and password. The fetch promise is then converted to JSON and passed to handleResult().

Response Headers and Body

Both in the case of a simple GET request or something like a POST request that involves headers, the promise that is returned from the fetch includes headers and a body. The body is captured with a .then such as .then(response => response.json()). The response headers provide clues that as to the status of the request, an important tool for developers to create a good user experience. A common example we see all the time is an alert message on a login form if the username or password is typed incorrectly.

Error handling with a fetch promise
Error handling with a fetch promise

Error Handling with Header Data

When a promise isn’t successful, we want to capture the information from the headers to let the user know why. Using a .catch and checking the response.status are our two main tools to work with.

.Catch: Including a .catch after all .then’s in the promise chain, will allow you to capture any 500 level errors.

Http status codes: Only a 500 level status code will throw an error that a .catch will capture. Including a .then that checks the status and throws a new Error with a message will allow the .catch to access the message. This way, all of your error handling can be done within a single function.

Thanks for reading!

Full-Stack Software Engineer, Designer, and salsa dancer.