DEV Community

Dane Dawson
Dane Dawson

Posted on • Updated on

Introduction to fetch() in JavaScript

This article series will use Ruby on Rails as a backend and JavaScript as the front end.

As I was learning JavaScript, one of the most confusing aspects of database interactions was the fetch() function. It is one of the most commonly used ways to interact with APIs, and while it has an amazing amount of functionality we will focus on it's most basic application, using the following format:

//Setting our host URL as a constant for easy reference
const URL = "http://localhost:3000"
//We will probably not talk much about options this article, but here is an example one
options = {
      method: "METHOD",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ dataKey1: dataValue1, dataKey2: dataValue2 }),
    };

//This is the actual series of functions for a fetch request. 
//However, the above options and URL are just examples of possible text
//This series of code would actually be inneffective in practice 
//so we are focusing on the structure rather than specific content.
fetch( URL, options)
.then(response=>(response.json()))
then(json=>(console.log(json)))

First, let me break down what this series of lines will do at a base level. The first line:

fetch( URL, options)

This will send a request (included in the options) to the specified URL (which we are saying is a local server we are hosting at http://localhost:3000). There is a lot to unpack in the options, but the first fetch request almost any app will make is a GET request, pinging the database for some information from the API. One of the wonderful things about fetch is that if you are only doing a GET request you can actually leave the options variable blank and it will assume you are fetching information. Example:

//Global constant for database URL
const URL = "http://localhost:3000"
//Calling fetch on that url
fetch( URL )

Will send a GET request to whatever URL you send it. What will happen is fetch will send out a request to that URL, and if the URL is valid, it will return a promise. Most errors you will get at this point are because either the url is entered incorrectly or the database doesn't have the routes connected for request you are making at that URL. It is worth looking into what a promise fully entails, but a good foundational understanding is that the database was reached, the route connected, and it returned a notification saying "I got your request, I will send information as soon as I can". Once the information is retrieved and packaged at the server, it will send a response that is normally a JSON string.

Some quick words about asynchronous functions

For me, fetch was the first asynchronous function I had contact with, and it's the asynchronous nature of this function that requires the subsequent .then() functions. Normally, when JavaScript runs, it will read through the entire document once, and then run the code line by line. By nature, most code is synchronous so as soon as one line finishes being read it is computed immediately and the next line is executed. Fetch(), however, knows that it may take time to get the response back from the server, so after running the fetch request it will immediately move on to the next line of code...but our fetch won't have returned anything except a promise!

This brings us to the next lines of the fetch chain:

//Global constant for database URL
const URL = "http://localhost:3000"
//Calling fetch on that URL. This will instantly return a promise (if URL is valid databse).
fetch( URL )
//Then, once the response has been returned, convert the JSON string to an object
.then(response=>response.json())

As we now covered, the fetch will first return a promise followed (usually very quickly) by a response. This response will hold all the information pulled from your GET request, but it will hold it in a JSON string. While a JSON string is very useful for data sending (it is one long, easily digestible string with all negative space removed), it is difficult for most humans to interact with a JSON string comfortably. Our first action is to take this string and turn it into something we can actually manipulate, a JSON object. Thankfully, JavaScript has a built in function .json() to turn a JSON string into a JSON object. This, however, is yet another asynchronous function as the system won't know how long it will take to fully convert this string. All this means is we tack on one more .then to take that JSON object and do whatever we want to with it. This example is simply logging the object in the console, which is a good first step with a fetch to make sure you have the data you want in the format you want it.

//Global constant for database URL
const URL = "http://localhost:3000"
//Calling fetch on that URL. This will instantly return a promise (if URL is valid databse).
fetch( URL )
//Then, once the response has been returned, convert the JSON string to an object
.then(response=>response.json())
//Then, once the string has been converted into an object, console.log the object
.then(json=>console.log(json))

In this current setup we have created a URL variable that just hits a server at it's root folder. A practice I have found useful is setting the server locations you will be targeting as global constants. Note, all these names used so far are simply placeholders for legibility in this walkthrough, you can use anything you want to reference the variables. If you were fetching an API to get a collection of users, you may do like the following:

//Global constant for user database URL
const userURL = "http://localhost:3000/users"
fetch( userURL )
.then(response=>response.json())
.then(users=>console.log(users))

If this works correctly, we should have in our console a list of every user object in our database. You could easily return the users, or embed another function that renders components, divs, or any other application of those objects you want.

If you wanted to target a specific user by id, you could do a targeted fetch like the following:

//Global constant for user database URL
const userURL = "http://localhost:3000/users"
//You can define this userId through an input value or any other way you'd like
let userId = 1
//This is the same as typing "http://localhost:3000/users/1" but open to dynamic change
fetch( userURL+"/"+userId )
.then(response=>response.json())
//this will now only return the user found at the id given
.then(user=>console.log(user))

Now that we have the basic foundations of GET requests, all the other requests work very similarly except the presence of the options.

Click HERE to see a basic introduction to full CRUD fetch requests!

Top comments (2)

Collapse
 
supermcreeper profile image
supermcreeper

Useful info!

Collapse
 
daulen135 profile image
Daulen135

Thanks, useful info!