Skip to content

Instantly share code, notes, and snippets.

@harrisonmalone
Last active June 1, 2019 03:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save harrisonmalone/61aa2221ae3caed9ef38213b3f87e60f to your computer and use it in GitHub Desktop.
Save harrisonmalone/61aa2221ae3caed9ef38213b3f87e60f to your computer and use it in GitHub Desktop.

Lecture ✍️

What is a promise in real life

A promise in real life is something that you say you'll do at some time in the future.

i promise I'll pay you back for that lunch!

You'll pay them back at some time in the future.

The amount of time this takes will depend on how reliable you are but at the end of the day eventually you'll have to do the work of asking for the bsb and account details, going to your phone bank app and sending across the bank transfer.

The final payload of this process is when your friend receives the money a few days later when they check their bank account 💰.

i sent the funds across!

Or maybe you later realise that you don't have any money in your bank account to pay your friend back 🤪. The promise has to be broken!

You'll have to send your friend a message saying:

sorry I have no money 🤷‍♂️

Relating this to APIs

You'll hardly ever have to write your own javascript promises but you'll be using them all the time with your own APIs.

Think of this concept in terms of dealing with the Pokemon API we played with a while ago in ruby.

We sent up a request to the API to get the Pokemon data; the Pokemon data then came back to us successfully. We didn't know how long the data was going to take to come back to us; theoretically it could have been a giant amount of Pokemon data we were after that takes around 3 seconds to come back or it could have been a single Pokemon object which takes around half a second to return.

This is the revolved value (the success value).

But... what if the server had been down! What if there had been some kind of error in the Pokemon API! We'd get an error message of some kind.

This is the rejected value (the error value).

Whats the definition of a javascript promise

A promise is an object that produces a single value some time in the future.

This is either a resolved value (successfully receiving the data payload) or a rejected value (an error message).

Using promises with APIs

You might of heard of this word AJAX before.

AJAX stands for Asynchronous JavaScript and XML; it's a way we can use javascript to request data from an external source like an API. Since we are usually relying on another server physically located somewhere else in the world, we need to do this asynchronously.

This is an AJAX request in action in javascript.

const pokePromise = fetch("https://pokeapi.co/api/v2/pokemon/?limit=150")
console.log(pokePromise)

To make an AJAX request in javascript we use the fetch function. This takes a string parameter containing the URL of the server we want to fetch data from and returns a promise.

fetch is a Web API (we'll talk more about this next week) which means it's not included in node. We need to install a package to make fetch work in node.

$ npm i node-fetch

Our code from before will now look this this.

const fetch = require('node-fetch');
const pokePromise = fetch("https://pokeapi.co/api/v2/pokemon/?limit=150")
console.log(pokePromise)

Let's talk about what is being console.logged right now.

We can see a promise object that says pending. The promise will always log pending as long as its results are not resolved yet. Regardless of the promise state (resolved or still pending) you must call another method .then on the promise to capture the results.

const pokePromise = fetch("https://pokeapi.co/api/v2/pokemon/?limit=150")
pokePromise
  .then((response) => {
    console.log(response)
  })

There's a lot of new concepts coming together here. Let's look at it.

In it's most basic terms this code can be read as:

fetch data from this url and then do this with it

To use the response data we need to pass a callback function to the promise's then method, which the promise executes when it receives a response from the server. The response is passed into the function as a parameter, providing access for us to actually use it...once it exists.

But we still don't have the data... yet 🤪.

We have a response body and we need to pull the JSON data out it. To do that we can use the .json() method. This returns another promise which we can then use a .then on again.

const pokePromise = fetch("https://pokeapi.co/api/v2/pokemon/?limit=150")
pokePromise
  .then((response) => {
    return response.json()
  })
  .then((data) => {
    console.log(data)
  })

Boom we have some pokemon 🎉!

For a deeper explanation about promises check out this article.

Why promises

When we make an AJAX request we get back a promise which is asynchronous meaning it does not wait for the response to come back from our API before executing the next line in the file.

This may seem confusing at first but javascript operates on a single thread, meaning it can only execute one command at a time.

Therefore, we need to make sure that commands that rely on external processes - such as our API - are not blocking, or do not hold up other commands.

Blocking is explained really well in this post on the node.js website.

So we can say that promises are a key design choice that allows for higher throughput and more performant code.

More on promises

Later on we'll cover:

  • How to handle rejected promises
  • How to write our own promise objects
// 1) Make sure node-fetch is installed
// 2) We'll be using the GitHub API to play with promises; I firstly want you to figure out what the url is to list all of my gists (my username is harrisonmalone) https://developer.github.com/v3/gists/#list-a-users-gists
// 3) List all of my gists using the promise syntax we just learnt
// 4) Figure out how to pass params to return all of my gists in one go https://developer.github.com/v3/#pagination
// example of raw javascript promise
// this isn't that important to remember apart from one question in a javascript quiz we'll do eventually (after maths)
const myPromise = new Promise((resolve, reject) => {
const num = 4
if (num > 5) {
resolve(num)
} else {
reject("number is less than 5")
}
})
// .then connected to the resolve
.then((num) => {
console.log("inside of .then")
console.log(num)
})
// .catch is connected to the reject
.catch((error) => {
console.log("inside of catch")
console.log(error)
})
// example of consuming a javascript promise
// by consuming i mean we don't write the promise ourselves, we just make a http request and get a response which is a promise
const fetch = require('node-fetch')
const pokemonPromise = fetch("https://pokeapi.co/api/v2/pokemon/?limit=150")
// to access the completed promise use .then
.then((response) => {
// .json() pulls out the json from the response body
return response.json()
})
.then((json) => {
console.table(json.results)
})
.catch((err) => {
console.log('in the catch')
console.log(err.message)
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment