Good Dog Javascript, Now Fetch!

Jessica Bradham
6 min readJun 23, 2021

I don’t think I’m capable of writing an article about the Javascript Fetch API without making Dad jokes, and referencing cheesy memes, because there are just too many good ones. So brace yourself. We’re about to break down Fetch, Promises, and Json.

Stop trying to make Fetch happen!

The first thing to know is that Fetch requests are asynchronous. Asynchronous code behaves by creating independent stacks so your code can run separately, allowing multiple things to run at the same time. As opposed to synchronous code which is more like a really long to-do list where a task can’t be completed until it finishes the previous tasks. It can be tricky to keep these words separate, especially if you have ADD like I do, so I’m going to give you a pro tip. Try to associate the behavior with method. If somebody were to ask you to describe how Fetch requests are asynchronous, try to focus on how you know Fetch behaves, rather than the word itself. You know fetch doesn’t stop an entire program to complete its task. So you can use context to help keep the words straight.

Aren’t they though?

The next thing to know about Fetch is that it returns a promise. We can literally write:

console.log(fetch(‘https://pokeapi.co/api/v2/pokemon'));

We don’t need to write anything other than that, and we’ll see in our console that it has returned

Promise {<pending>}

So the next big question is, what is a promise?

Promises Promises, Check this hand cause I’m marvelous

Promises are objects that represent an asynchronous event and whatever results from it, whether it succeeds or fails, they are shamelessly promising results, they’re just being kind of vague about what those results are going to be, as you could see by my ‘pending’ promise.

In order to have our promise return successful we’re going to use .then to log the response of Fetch.

fetch(‘https://pokeapi.co/api/v2/pokemon')
.then(resp => console.log(resp))

Promise {<pending>}

  1. Response {type: “basic”, url: “https://pokeapi.co/api/v2/pokemon", redirected: false, status: 200, ok: true, …}
  2. body: (…)
  3. bodyUsed: false
  4. headers: Headers {}
  5. ok: true
  6. redirected: false
  7. status: 200
  8. statusText: “”
  9. type: “basic”
  10. url: “https://pokeapi.co/api/v2/pokemon"
  11. __proto__: Response

At this point we can see a response but it is not usable data. But For example if I try typing

fetch(‘https://pokeapi.co/api/v2/pokemon')
.then(resp => console.log(resp.body))

I’ll get

ReadableStream {locked: false}

But if I were to do this instead (and here I switched to a specific Pokemon to lower the amount of results I was getting).

fetch(‘https://pokeapi.co/api/v2/pokemon/3')
.then(resp => resp.json()) //Converting the response to a JSON
.then(json => console.log(json.abilities)); //Logging the JSON and calling the .abilities key

I’m now able to access this data

  1. (2) [{…}, {…}]
  2. 0: {ability: {…}, is_hidden: false, slot: 1}
  3. 1: {ability: {…}, is_hidden: true, slot: 3}
  4. length: 2
  5. __proto__: Array(0)

So I guess at this point it’s time to ask the question, what the heck is JSON anyway?

Me too Andy. Me too.

JSON stands for Javascript Object Notation. This is something I never remember when I’m asked if I’m going to be totally honest, and I’ve been using JSON files for years. Literally. I built a portfolio site a couple years ago that used a JSON file to populate all of the projects, and main information so it could be easily updated. I created a pizza website where I made a menu out of JSON file so it could be easily updated. I used to make Read Along Audio books where we had to create long JSON files of audio timestamp data for when each word in the audio file started. And Stopped. Started. And Stopped. JSON files are extremely versatile and valuable, and has a million uses. They are even used as databases! (Though I wouldn’t call it my favorite use case, I would probably say I prefer it to logging timestamped audio though. Let’s not to that again. Ever.)

So what is it? A really watered down explanation would be that JSON format allows us to store/handle/process information in a lightweight format using arrays and key value pairs (think Hashes). By converting our response to json, we are making it into a usable format.

Now I know what you’re thinking, it’s all well and good, but what happens if your Fetch request isn’t successful!?

Don’t worry Gru, we’ve all been there.

Some nefarious user is trying to search for a Pokemon that doesn’t exist.

You see that minion on the far left looking directly at the camera, almost not in the frame? I’m pretty sure it was him.

So what happens now!? Everything just breaks? Those little chicken mcnuggets wish! Because we have a solution for that, and it’s called Catch. So when those walking mischievous mini corndogs get up to no good, all we need is this extra line

Fetch(‘https://pokeapi.co/api/v2/pokemon/3')
.then(resp => resp.json())
.then(json => console.log(json.abilities))
.catch(error => console.log(“Knock it off or I’m feeding you to the mean girl from the first meme!”))

And they’ll have a frightening warning delivered to them.

Now let’s look at customizing this Fetch request. Because right now this is pretty generic.

Some common http methods are POST, GET, PUT, & DELETE. This horse seems to like POST best.

If we want to further customize our Fetch request we can open a block after the initial URL in the Fetch() like this.

fetch(‘https://pokeapi.co/api/v2/pokemon/3', {
})
.then(resp => resp.json())
.then(json => console.log(json))
.catch(error => console.log(error))

And while there are TONS of options we could discuss in here, I’m going to specifically focus on 3 today. Method, Body, and Headers.

Did you think I’d be out of memes yet?

Method is where we are going to tell the fetch request what type of request we are making. As you saw in my previous examples, the default behavior is a GET method, but if you are wanting to create, delete, or update, you’ll need to explicitly state your method. Luckily this is pretty easy!

fetch(‘https://pokeapi.co/api/v2/pokemon/3', {
method: ‘POST’
})
.then(resp => resp.json())
.then(json => console.log(json))
.catch(error => console.log(error))

I know you are sitting over there shouting “IT CAN’T BE THAT EASY!?” But it is. It really is. The next step though is to convert that data into something our program can understand easier. Just like how we converted the response to JSON, when we are posting an object we want to convert it to a JSON string for our program.

fetch(‘https://pokeapi.co/api/v2/pokemon/3', {
method: ‘POST’,
body: JSON.stringify(data)
})
.then(resp => resp.json())
.then(json => console.log(json))
.catch(error => console.log(error))

An important thing to remember, straight from MDN docs, is that the header content type must match the body type. So if you are using JSON.stringify(data), you want to match your type with ‘Content-Type’: ‘application/json’ so they are both JSON types. Likewise ‘Accept’ will make it known which content types the client can understand.

fetch(‘https://pokeapi.co/api/v2/pokemon/3', {
method: ‘POST’,
body: JSON.stringify(data),
headers: {
‘Content-Type’: ‘application/json’,
‘Accept’: ‘application/json’
}
})
.then(resp => resp.json())
.then(json => console.log(json))
.catch(error => console.log(error))

Well, that’s a pretty thorough breakdown of using fetch in Javascript. If you’d like to know more…

Did you really think there wouldn’t be one more meme?

Just kidding. Aliens don’t use fetch, they use probe. I’d rely on MDN for documentation. At least until the aliens give up the probes.

--

--

Jessica Bradham

Jessica is a Software Engineer who has been coding since she was a teen, she has 2 giant dogs, a love of javascript, and hates Papyrus (the font).