# APIs with Fetch and Axios

### Learning Objectives

*After this lesson, you will be able to:*

* Create a React component that calls an API
* Identify the pieces of a `fetch()` and `axios()` call with `React`.
* Use `fetch` inside a `React` component
* Use `axios` inside a `React` component

## Introducing `fetch()`

So... we know what an API is. Now what?

How can we use an API to dynamically manipulate the DOM with the given data? We can use `fetch()`.

In the past, these have been called **AJAX** requests. As you'll come to learn, `fetch()` allows us to build single page applications that do not require refreshes.

**AJAX**, which stands for "Asynchronous Javascript and XML," is the method through which we are able to make HTTP **requests**. The standard requests we will be making are `GET` `POST` `PUT` `PATCH` and `DELETE`.

| Type of Request | What's It Do?                                                                 |
| --------------- | ----------------------------------------------------------------------------- |
| `GET`           | Read (*'give me movie names from your database'*)                             |
| `POST`          | Create (*'here's a new movie for your database'*)                             |
| `PATCH`         | Update (*'hey, this movie has a new title'*))                                 |
| `PUT`           | Update (*'hey, this movie totally changed'*)                                  |
| `DELETE`        | Delete (*'that movie is so bad you should just take it out of the database'*) |

The browser packages this together using `fetch()` and sends it off to a server. The server then listens to your request and provides a **response**. It looks something like this:

![Request/Response](https://github.com/WDI-SEA/wdi-23-lessons/raw/master/w08/d4/assets/request-response.png)

When you browse to your favorite websites, your browser is making a request and the server is providing a response. `fetch()` allows us to perform the same type of requests over a network. Imagine fetching weather information and rendering it on your website. You can use `fetch()` to build these applications.

#### Taking a look at `fetch` in action

That was a lot! Let's take a look at `fetch()` in action.

Imagine we want to `fetch()` the number of astronauts currently aboard the International Space Station (ISS). Good thing there is an API for that, right? This API allows us get the information using the following URL:

```
http://api.open-notify.org/astros.json
```

The API provides a response that looks like the following:

```javascript
{
    "number": 5,
    "people": [
        {"craft": "ISS", "name": "Oleg Novitskiy"},
        {"craft": "ISS", "name": "Thomas Pesquet"},
        {"craft": "ISS", "name": "Peggy Whitson"},
        {"craft": "ISS", "name": "Fyodor Yurchikhin"},
        {"craft": "ISS", "name": "Jack Fischer"}
        ],
        "message": "success"
}
```

> If you'd like, you can copy and paste the API URL into a browser to see this happen.

This particular API tells us the number of people currently in space on the ISS and their names. It also happily gives us "message: success" so we know it worked!

We can fetch this JSON easily using Javascript.

How? The skeleton code looks like this:

```javascript
fetch(url)
  .then(function(response) {
    // Here you get the data to modify or display as you please
    })
  })
  .catch(function(err) {
    // If there is any error, you will catch it here
  })
```

Let's look at what we would apply this for our astronauts:

```javascript
let issApi = 'http://api.open-notify.org/astros.json';
fetch(issApi)
  .then(function(response) => {
    return response.json();
  }).then(function(json) => {
    console.log('JSON from the ISS', json);
  }).catch(function(err) => {
    console.log('An error occured while parsing!', err);
  })
```

That's as simple as `fetch` is. While there are other ways to handle the response (such as `html` or `blob`), this approach makes writing requests to APIs and other network calls in Javascript easy.

> *Production Warning!* It is important to note that while this is an ES6 standard, [some browsers such as Internet Explorer](http://caniuse.com/#search=fetch) do not support it; yet Edge does. You may need a polyfill for live projects. If you need a polyfill for a production project, [Github's polyfill is very popular](https://github.com/github/fetch).

## Codealong - Kanye West Quotes

It is time for you to build a very simple component that shows a randomly generated Kanye West Quote. We'll do this using the [Kanye Rest](https://api.kanye.rest/). Before doing so, challenge yourself to a mini quiz.

**Q: Which React method should API calls be made from?**

`useEffect()`. Per the [React documentation](https://reactjs.org/docs/faq-ajax.html), *If you need to load data from a remote endpoint, this is a good place to instantiate the network request.*

**Q: What does it mean to make `GET` request?**

We are asking the server to send us data to read. To `GET` means to "read."

## Fetching Kanye in a React Component

Let's go back to your blog project (so make sure it's running!).

You can use `fetch()` API directly inside of a React Component to render a quote. We'll be using the `Home` component, so open `Home.js` to edit.

The official [React documentation](https://reactjs.org/docs/hooks-effect.html) tells developers that any network requests should be placed inside of the *useEffect* method.

* Start by changing the `Home` component to have an empty `useEffect()` method.
* Set the stage for returning a quote in the `div` by changing the text to be an `<h1>` with the text "My favorite Kanyw quote:"

## Let's use axios instead!

`fetch` is great and all... but let's take this opportunity to test out another common library! `axios` is Promise based HTTP client for the browser and node.js! More detailed information can be found in their [README on github](https://github.com/axios/axios).

```javascript
import React, { useEffect } from 'react';
function Home () {
   useEffect(() => {
    fetch("https://api.example.com/items")
      .then(res => res.json())
      .then(
        (result) => {
          setIsLoaded(true);
          setItems(result);
        },
        // Note: it's important to handle errors here
        // instead of a catch() block so that we don't swallow
        // exceptions from actual bugs in components.
        (error) => {
          setIsLoaded(true);
          setError(error);
        }
      )
  }, [])

}


class Home extends Component {

  componentDidMount() {
      /* nothing here... yet! */
  }

  render() {
    return (
      <div>
        <h1>My favorite Kanye quote:</h1>
      </div>
    )
  }
}


export default Home
```

or with a functional component...

```javascript
import React, {useEffect} from 'react'

const Home = () => {
   useEffect() {
      /* nothing here... yet! */
   }

   return (
      <div>
        <h1>My favorite Kanye quote:</h1>
      </div>
   )
  }
```

We can now tell our component to fetch a Kanye quote and then set it to our state. We do this by adding the `axios.get()` call inside of *componentDidMount()*.

Calling `this.setState()` then triggers a re-*render* inside of our component.

You should have this inside your functional component...

```javascript
import React, {useState, useEffect} from 'react'
import axios from 'axios'

function Home() {
   let [kanye, setKanye] = useState('')

   useEffect(() => {
    let kanyeRest = 'https://api.kanye.rest/';
    axios.get(kanyeRest)
    .then(response => {
          setKanye(response.data.quote)
        })
    .catch(err => console.log(err.message))
   }, [])

   return (
        <div>{kanye}</div>
   )
}
```

Let's test it out!

and one more time, as a functional component:

```javascript
if (kanye) {
  return (
    <div>
      <h1>My favorite Kanye quote:</h1>
      <div>{kanye}</div>
      <p>Lo, my heart doth swoon... Such a way with words.</p>
    </div>
  );
} else {
  return (
   <div>
      <h1>My favorite Kanye quote:</h1>
      <div>Loading...</div>
   </div>
);
}
```

You're done! Your `Home` page should load a random Kanye quote!

For more information than you probably ever wanted to know about fetching data in React, these articles by Robin Weiruch make for a pretty complete resource:

* [How to Fetch Data in React](https://www.robinwieruch.de/react-fetching-data/)
* [Fetching Data with React Hooks](https://www.robinwieruch.de/react-hooks-fetch-data/)
  * 🏴‍☠️ BEWARE! There be HOOKS here! 🏴‍☠️
