Async/Await and Handling Promises from our Api

Async/Await and Handling Promises from our Api

One of the objectives we have in the Intro to Web class is to build a website that brings in data from an api. We will use that data to supply some interactive features on the web pages.

To this point, in order to get data from our chosen api, we used the fetch() method. Here is an example of how we accomplished this, using the chuck norris api and the example shared via the mdn documentation.

fetch('https://api.chucknorris.io/jokes/random')
  .then((response) => response.json())
  .then((data) => console.log(data));

This results in an object being logged to our console. That object contains our random fact about Chuck Norris. However, to get this object, we had to use promise chaining. Let us take this example and work through each line to gain a better understanding of what is occurring.

When we console.log the first line, what we get back is a promise:

console.log(fetch('https://api.chucknorris.io/jokes/random'))

// Promise { <pending> }

When the promise resolves, it does not contain the information we are looking for, so on the second line, we use the json() method to convert the response into a javascript object.. The resulting output of using the json() method is once again a promise.

fetch('https://api.chucknorris.io/jokes/random')
  .then((response) => console.log(response.json()))

// Promise { <pending> }

Therefore, we need to add one more of our .then() handlers that will receive the result of the json() method and allow us to access that result.

fetch('https://api.chucknorris.io/jokes/random')
  .then((response) => response.json())
  .then((data) => console.log(data));

// Result
{
   "categories": [],
    "created_at": "2020-01-05 13:42:21.795084",
   "icon_url": "https://assets.chucknorris.host/img/avatar/chuck-norris.png",
    "id": "YF6DhfKRQlOPgn4kcswbOA",
    "updated_at": "2020-01-05 13:42:21.795084",
    "url": "https://api.chucknorris.io/jokes/YF6DhfKRQlOPgn4kcswbOA",
    "value": "When bored and just for shits and giggles, Chuck Norris likes to walk around skid row with hundred dollar bills hanging out of his pockets."
}

Now we have reviewed what we accomplished previously, but with a better understanding of what we are doing with each promise. The next question we can ask is: "Is there another way to accomplish this with a similar result?"

That is where async/await comes into the discussion.

An async function allows us to handle asynchronous javascript, dealing with the promises that we need to wait for. One key characteristic of these two keywords is that the await keyword can only be used within an async function.

Let's rewrite the example we had before using async/await.

Step One: Create the function

const getFact = () => { }

Step Two: Make the function an async function

const getFact = async () => {}

Step Three: Now we can use the async function to get our data

const getFact = async () => {
    const response = await fetch('https://api.chucknorris.io/jokes/random')
    const data = await response.json()
    console.log(data)
}

console.log(getFact())

// line 7: Promise {<pending>}
// line 4: {our object with random fact}

What we should notice here is that when we console logged the getFact function we received a promise. That is because an async function will always return a promise. The value of using the async function is for a couple of reasons:

  1. It is cleaner to read.
  2. We can handle all of our promises within the async function and then only need to manage one promise returned by the called function.

To complete this exercise, let's go ahead and return a value from our function instead of console logging it.

const getFact = async () => {
    const response = await fetch('https://api.chucknorris.io/jokes/random')
    const data = await response.json()
    return data
}

getFact().then(data => {console.log(data)})

//{
//    "categories": [],
//    "created_at": "2020-01-05 13:42:22.089095",
//    "icon_url": "https://assets.chucknorris.host/img/avatar/chuck-norris.png",
//    "id": "WWXokdqSRgqpWzmyWNwBnQ",
//    "updated_at": "2020-01-05 13:42:22.089095",
//    "url": "https://api.chucknorris.io/jokes/WWXokdqSRgqpWzmyWNwBnQ",
//    "value": "Chuck Norris has a deal: no paparazzi ever take pictures of him or follow him, //and he won't murder that TMZ guy with his own big coffee mug."
//}

That is the conclusion of our review of async/await.

I admit that learning to handle promises and asynchronous javascript was one of the more challenging concepts to learn when beginning with javascript. I do believe that the introduction of async/await helped me, but it is important to have a good understanding of promises to fully appreciate the value async/await provides.