---
description: Creating calls to various APIs using 4 techniques
---

# HTTP Requests

## Summary:

1. JavaScript is the language of the web because of its asynchronous capabilities. AJAX, which stands for Asynchronous JavaScript and XML, is a set of tools that are used together to take advantage of JavaScript’s asynchronous capabilities.
2. There are many HTTP request methods, two of which are GET and POST.
3. GET requests only request information from other sources.
4. POST methods can introduce new information to other sources in addition to requesting it.
5. GET requests can be written using an XMLHttpRequest object and vanilla JavaScript.
6. POST requests can also be written using an XMLHttpRequest object and vanilla JavaScript.
7. Writing GET and POST requests with XHR objects and vanilla JavaScript requires constructing the XHR object using `new`, setting the `responseType`, creating a function that will handle the response object, and opening and sending the request.
8. To add a query string to a URL endpoint you can use `?` and include a parameter.
9. To provide additional parameters, use `&` and then include a key-value pair, joined by `=`.
10. Determining how to correctly write the requests and how to properly implement them requires carefully reading the documentation of the API with which you’re working.

## Four HTTP Requests

The four most commonly used types of HTTP requests are GET, POST, PUT, and DELETE.

* GET : retrieving info from a website
* POST : posting info to the source

Perform GET and POST requests using JavaScript's XHR object :&#x20;

1. Datamuse API for GET requests
2. Rebrandly URL shortener API for POST requests

{% embed url="https://www.codecademy.com/articles/rebrandly-signup" %}
Register Rebrandly account and obtain API key
{% endembed %}

## GET Requests : Asynchronous JavaScript & XML (AJAX)

{% embed url="https://developer.mozilla.org/en-US/docs/XML_introduction" %}

* &#x20;enables requests to be made after initial page load
* How to create an XHR GET request:

![The standard template](https://2068334946-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fow1iM27u7disHeJiSlBC%2Fuploads%2FKmiADUZwHE663ZgfdvpP%2Fimage.png?alt=media\&token=67204b57-224c-4f3c-9651-4fb526bec2a9)

### # XHR GET Requests

This section we create the boiler plate code for an AJAX GET request using an XMLHttpRequest Object:

```javascript
const xhr = new XMLHttpRequest();
const url = "https://api-to-call.com/endpoint";
xhr.responseType = 'json'; //format the response in Javascript Object Notation
xhr.onreadystatechange = () => {
  if (xhr.readyState === XMLHttpRequest.DONE) {    //check if request is finished
    return xhr.response;  // This response will contain the data that we’re
    // getting back from the request.       
  }
}

xhr.open('GET', url); //.open() creates new request, pass in type and request url
xhr.send()
```

### # Using AJAX GET request to Datamuse API to search for words that rhyme

```javascript
// Information to reach API
const url = "https://api.datamuse.com/words?"; //direct requests here
const queryParams = 'rel_rhy='; // start of query string to find words that rhyme

// Selecting page elements
const inputField = document.querySelector('#input');
const submit = document.querySelector('#submit');
const responseField = document.querySelector('#responseField');

// AJAX function
const getSuggestions = () => {
  const wordQuery = inputField.value;
  const endpoint = `${url}${queryParams}${wordQuery}`;
  const xhr = new XMLHttpRequest();
  xhr.responseType = 'json';
  xhr.onreadystatechange = () =>{
      if(xhr.readyState === XMLHttpRequest.DONE) {
        renderResponse(xhr.response);   //use renderRawResponse() to see raw data --> need another helper file for this script 
      }
  }
  xhr.open('GET', endpoint); //endpoint is destination
  xhr.send(); //send request to server
}

// Clear previous results and display results to webpage
const displaySuggestions = (event) => {
  event.preventDefault();
  while(responseField.firstChild){
    responseField.removeChild(responseField.firstChild);
  };
  getSuggestions();
}

submit.addEventListener('click', displaySuggestions);

```

![](https://2068334946-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fow1iM27u7disHeJiSlBC%2Fuploads%2F1W6RR4ssr7P7hyx8CCgc%2Fimage.png?alt=media\&token=94db9bca-9689-424c-bc71-9fba439077cb)

&#x20;In this exercise, we will create a request to set a topic and find adjectives that describe the input word using query strings.

A query string contains additional information to be sent with a request. The Datamuse API allows us to retrieve more specific data with query strings attached to the request URL.

* [Wiki: query string](https://en.wikipedia.org/wiki/Query_string)

A query string is separated from the URL using a `?` character. After `?`, you can then create a parameter which is a key value pair joined by a `=`. Examine the example below:

```
'https://api.datamuse.com/words?key=value'
```

If you want to add an additional parameter you will have to use the `&` character to separate your parameters. Like so:

```
'https://api.datamuse.com/words?key=value&anotherKey=anotherValue'
```

## XHR POST Requests

The major difference between a GET request and POST request is that a POST request requires additional information to be sent through the request. This additional information is sent in the _body_ of the post request.

![](https://2068334946-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fow1iM27u7disHeJiSlBC%2Fuploads%2FUw6DtTibBU43KKlRjF9z%2Fimage.png?alt=media\&token=7d6592a4-8184-418a-a136-e1606e89c2fb)

### # Standard Boiler plate code for POST Requests

```javascript
const xhr = new XMLHttpRequest();
const url = "https://api-to-call.com/endpoint";
const data = JSON.stringify({id: '200'});
// this converts a value to a JSON string, enabling us to send data to server
xhr.responseType = 'json';
// the below contain handler for when xhr state changes
xhr.onreadystatechange = () => {
  if (xhr.readyState === XMLHttpRequest.DONE) {
    return xhr.response;
  }
}

xhr.open('POST', url);
xhr.send(data); // this the only diff between GET and POST
//POST will send data in
```

### &#x20;# Using Rebrandly API to shorten long URLs

```javascript
// Information to reach API
const apiKey = '49dbc48d3d2548d29a5c6bae1bc7deb9'; //rebrandly api key
const url = 'https://api.rebrandly.com/v1/links';

// Some page elements
const inputField = document.querySelector('#input');
const shortenButton = document.querySelector('#shorten');
const responseField = document.querySelector('#responseField');

// AJAX functions
const shortenUrl = () => {
  const urlToShorten = inputField.value;
  const data = JSON.stringify({destination: urlToShorten});
  const xhr = new XMLHttpRequest();
  xhr.responseType = 'json';
  xhr.onreadystatechange = () => {
    if (xhr.readyState === XMLHttpRequest.DONE) {
      renderResponse(xhr.response);
    }
  }
  xhr.open('POST', url);
  xhr.setRequestHeader('Content-type', 'application/json');
xhr.setRequestHeader('apikey', apiKey);
  xhr.send(data);

}
// Clear page and call AJAX functions
const displayShortUrl = (event) => {
  event.preventDefault();
  while(responseField.firstChild){
    responseField.removeChild(responseField.firstChild);
  }
  shortenUrl();
}

shortenButton.addEventListener('click', displayShortUrl);
// Input : https://medium.com/@codecademy/breaking-the-coding-language-barrier-bf24652c3c60
//Output : Your shortened url is: rebrand.ly/oa3uv8w
```

## Combining Promises to AJAX

`This section we learn to use fetch()`, which uses promises to handle requests. Then, we will simplify requests using `async` and `await`.

We’ll use the Datamuse API for GET requests and Rebrandly URL Shortener API for POST requests.&#x20;

### # fetch() to GET request

Sample:

* Inside of the `response` callback function, check the `ok` property of `response` inside of a conditional statement. In the code block of the conditional statement, return `response.json().`
* The reason we’re testing the `ok` property of the response object is that it will be a Boolean value. If there were no errors `response.ok` will be `true` and then your code will return `response.json()`.
*   Add a second argument to `.then()`, it will be an arrow function that will handle our failures. Separate the first callback function from the second with a comma. The second callback function takes a single parameter, `networkError`.

    In the code block of the second callback function, log `networkError.message` to the console.

    If we could not reach the endpoint at all, e.g., the server is down, then we would get this `networkError`.
*   Chain another `.then()` method to the end of the first `.then()` method.

    Pass the new `.then()` method a callback function that takes `jsonResponse` as its parameter and return `jsonResponse`.

    The second `.then()`‘s success callback won’t run until the previous `.then()` method has finished running. It will also not run if there was an error was thrown previously.

```javascript
// BOILER PLATE CODE FOR GET using fetch() and .then()
fetch('https://api-to-call.com/endpoint').then(response => {
  if (response.ok) {
    return response.json();
  }
  throw new Error('Request failed!');
}, networkError => {
  console.log(networkError.message);
}).then(jsonResponse => {
  return jsonResponse;
});
```

The `fetch()` function:

* Creates a request object that contains relevant information that an API needs.
* Sends that request object to the API endpoint provided.
* Returns a promise that ultimately resolves to a response object, which contains the status of the promise with information the API sent back.

Extension of the datamuse API project:

```javascript
// Information to reach API
const url = 'https://api.datamuse.com/words';
const queryParams = '?sl=';

// Selects page elements
const inputField = document.querySelector('#input');
const submit = document.querySelector('#submit');
const responseField = document.querySelector('#responseField');

// AJAX function
const getSuggestions = () => {
  const wordQuery = inputField.value;
  const endpoint = `${url}${queryParams}${wordQuery}`;
  
  fetch(endpoint, {cache: 'no-cache'}).then(response => {
    if (response.ok) {
      return response.json();
    }
    throw new Error('Request failed!');
  }, networkError => {
    console.log(networkError.message)
  })
}

// Clears previous results and display results to webpage
const displaySuggestions = (event) => {
  event.preventDefault();
  while(responseField.firstChild){
    responseField.removeChild(responseField.firstChild);
  }
  getSuggestions();
};

submit.addEventListener('click', displaySuggestions);

```

### # fetch() POST Requests

Notice that the initial call takes two arguments: an endpoint and an object that contains information needed for the POST request. The rest of the request is identical to the GET request.

![](https://2068334946-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fow1iM27u7disHeJiSlBC%2Fuploads%2Fsg4SK7iT8mk1QU2AGakN%2Fimage.png?alt=media\&token=54f90b12-8074-45a1-8bfc-5d509eb59275)

```javascript
fetch('https://api-to-call.com/endpoint', {
  method: 'POST',
  body: JSON.stringify({id: "200"})
}).then(response => {
  if(response.ok){
	  return response.json();  
  }
	throw new Error('Request failed!');
}, networkError => {
  console.log(networkError.message);
}).then(jsonResponse => {
  console.log(jsonResponse);
})

//using Rebrandly API key with the boiler plate code
// Information to reach API
const apiKey = '<Your API Key>';
const url = 'https://api.rebrandly.com/v1/links';

// Some page elements
const inputField = document.querySelector('#input');
const shortenButton = document.querySelector('#shorten');
const responseField = document.querySelector('#responseField');

// AJAX functions
const shortenUrl = () => {
  const urlToShorten = inputField.value;
  const data = JSON.stringify({destination: urlToShorten})
  
	fetch(url, {
    method: 'POST',
    headers: {
      'Content-type': 'application/json',
      'apikey': apiKey
    },
    body: data
  })
}

// Clear page and call AJAX functions
const displayShortUrl = (event) => {
  event.preventDefault();
  while(responseField.firstChild){
    responseField.removeChild(responseField.firstChild)
  }
  shortenUrl();
}

shortenButton.addEventListener('click', displayShortUrl);

```

### Async GET Requests

we’re going to take what you’ve learned about chaining Promises and make it simpler using functionality introduced in ES8: `async` and `await`.

Review

* Using an `async` function that will return a promise.
* `await` can only be used in an `async` function. `await` allows a program to run while waiting for a promise to resolve.
* In a `try...catch` statement, code in the `try` block will be run and in the event of an exception/error, the code in the `catch` statement will run.

![](https://2068334946-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fow1iM27u7disHeJiSlBC%2Fuploads%2FIYsfzUTYxVRXThQLJtOu%2Fimage.png?alt=media\&token=ebfa8c98-768d-46f4-9a85-96dd42ce0deb)

```javascript
//BOILERPLATE CODE for GET requests using ASYNC AWAIT
const getData = async () => {
  try {
    const response = await fetch('https://api-to-call.com/endpoint');
    if (response.ok) {
      const jsonResponse = await response.json();
      return jsonResponse;
    }
    throw new Error('Request failed!');
  } catch (error) {
    console.log(error);	
  }
}
```

* Inside the `catch` code block, log `error` to the console.

Since this exercise is an example, we’re using `console.log()` to view the error. Generally, developers create a more sophisticated way of handling the error, like redirecting their users to another page, but logging is fine for us at the moment.

* We’ll have to save the returned promise in a variable called `response` using the `const` keyword. `response` will save the response of endpoint once that information has been sent back.
* Under `response`, create a conditional statement that checks if the `ok` property of the `response` object evaluates to a truthy value.
*   Inside the code block of the conditional statement, `await` the resolution of calling the `.json()` method on `response`.

    Save the returned object to a variable called `jsonResponse` using the keyword `const`.

    Since `.json()` is an asynchronous method we have to `await` until the promise status is resolved. Then we store the value to know what data the JSON holds.

```javascript
// DATAMUSE API SAMPLE CODE
// Information to reach API
const url = 'https://api.datamuse.com/words?';
const queryParams = 'rel_jja=';

// Selecting page elements
const inputField = document.querySelector('#input');
const submit = document.querySelector('#submit');
const responseField = document.querySelector('#responseField');

// AJAX function
// Code goes here
const getSuggestions = async () => {
  const wordQuery = inputField.value;
  const endpoint = `${url}${queryParams}${wordQuery}`;
  try {
    const response = await fetch(endpoint, {cache: 'no-cache'});
    if(response.ok){
      const jsonResponse = await response.json();
      renderResponse(jsonResponse);
    }
  } catch (error) {
    console.log(error);
  }
}

// Clear previous results and display results to webpage
const displaySuggestions = (event) => {
  event.preventDefault();
  while(responseField.firstChild){
    responseField.removeChild(responseField.firstChild);
  }
  getSuggestions();
}

submit.addEventListener('click', displaySuggestions);

```

### Async POST Requests

Review :

1. GET and POST requests can be created a variety of ways.
2. Use AJAX to asynchronously request data from APIs. `fetch()` and `async`/`await` are new functionalities developed in ES6 (promises) and ES8 respectively.
3. Promises are a new type of JavaScript object that represent data that will eventually be returned from a request.
4. `fetch()` is a web API that can be used to create requests. `fetch()` will return promises.
5. We can chain `.then()` methods to handle promises returned by `fetch()`.
6. The `.json()` method converts a returned promise to a JSON object.
7. `async` is a keyword that is used to create functions that will return promises.
8. `await` is a keyword that is used to tell a program to continue moving through the message queue while a promise resolves.
9. `await` can only be used within functions declared with `async`.

As with the other GET and POST requests that you’ve been making, an `async` POST request requires more information. Take a look at the diagram.

We still have the same structure of using `try` and `catch` as before. But, in the `fetch()` call, we now have to include an additional argument that contains more information like `method` and `body`.

![](https://2068334946-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fow1iM27u7disHeJiSlBC%2Fuploads%2FqYOqL65OHG7bG9JBJUlw%2Fimage.png?alt=media\&token=7bd72d30-cc3e-493a-84a3-6a1c2e8521ba)

## Project using Foursquare & OpenWeather API

To be continued 1/12/2021
