12. Fetching data

AJAX, an acronym for Asynchronous JavaScript And XML, is a technique that allows us to communicate with other services to get/add/modify/delete information asynchronously (after the web page has loaded). Today we still use the same strategy, except that we now have more modern APIs like Fetch. You can also think of it as: making an asynchronous HTTP request.

Fetching data from a server opens the door to an unlimited amount of information from other services (statistics, databases, calculations...) which, if handled properly, will enrich navigation with new HTML structures or elements that improve the experience.

For example, if I'm building a travel search engine, it would be nice to show the weather at the destination when a departure date is entered. In this case I would ask an external server (API) for that information and then create a section within the page with the temperature. Are those predictions in my code? No, not at all. I ask, they respond, and I display it.

API stands for: application programming interface. It can be internal to the language, like fetch itself, or external, like a service that lets us make HTTP requests to it.

AJAX example

When we manage information, regardless of the language or database, we have 4 basic actions available.

  • Create (Create).
  • Read (Read).
  • Update (Update).
  • Delete (Delete).

For short, this is called CRUD.

When we make HTTP requests, or requests in general, we have the same system, although we use verbs to communicate with the server.

  • GET: Read.
  • POST: Create.
  • PUT: Update.
  • DELETE: Delete.

Also called methods (Methods).

If I wanted to connect to an external API, we'd use the fetch function.

fetch('https://dominio.com/')
  .then(function(response) {
    // Transforms the response. In this case it converts it to JSON
    return response.json();
  })
  .then(function(json) {
    // Log to the console
    console.log(json)
  });

With the ES6 version of JavaScript, the tools for making AJAX requests were modernized, called fetch. On March 27, 2017, Safari implemented it, although Chrome and Firefox had already had it enabled since 2015. That's when it became a viable option to use, although you'll find many old examples around the web using XMLHttpRequest.

Its execution is asynchronous, so it will always return a Promise. To wait for it to finish we have 2 options: either use the then() function or run it inside an async function and wait with await.

async function hacerPeticion() {
  // Makes the request
  const miFetch = await fetch('https://dominio.com/');
  // Transforms the response. In this case it converts it to JSON
  const json = await miFetch.json();
  // Log to the console
  console.log(json);
}

hacerPeticion();

My recommendation is that you make calls following this last example, since it will be easier to structure and it's also faster to return results (we're talking about milliseconds, so don't lose your mind over it either). Still, be careful when doing a return, since it will return a promise.

GET

GET method

Using .then()

fetch('https://jsonplaceholder.typicode.com/users')
  .then(function(response) {
    // Transforms the response. In this case it converts it to JSON
    return response.json();
  })
  .then(function(json) {
    // We use the received information as needed
    console.log(json)
  });

Another version with an arrow function.

fetch('https://jsonplaceholder.typicode.com/users')
  .then((response) => response.json())
  .then((json) => console.log(json));

Using await

async function obtenerUsuarios() {
  // Makes the request
  const miFetch = await fetch('https://jsonplaceholder.typicode.com/users');
  // Transforms the response. In this case it converts it to JSON
  const json = await miFetch.json();
  // Log to the console
  console.log(json);
}

obtenerUsuarios();

Logs to the console.

[
  {
    "id": 1,
    "name": "Leanne Graham",
    "username": "Bret",
    "email": "Sincere@april.biz",
    "address": {
      "street": "Kulas Light",
      "suite": "Apt. 556",
      "city": "Gwenborough",
      "zipcode": "92998-3874",
      "geo": {
        "lat": "-37.3159",
        "lng": "81.1496"
      }
    },
    "phone": "1-770-736-8031 x56442",
    "website": "hildegard.org",
    "company": {
      "name": "Romaguera-Crona",
      "catchPhrase": "Multi-layered client-server neural-net",
      "bs": "harness real-time e-markets"
    }
  },
  {
    "id": 2,
    "name": "Ervin Howell",
    "username": "Antonette",
    ...

Parameters in the URL

In certain cases we need to include parameters in the URL. This is a particular case of the GET verb, since it's the only way to send settings to the server. The routes will have the following form:

https://dominio.com?query=barcos&page=4

The question mark symbol (?) separates the domain name from the parameters, whose format is always "parameter name" + "=" + "value". In the example above we can see the parameter query with the value barco, and the parameter page with the value 4. Parameters are separated with an &, and spaces or special characters (like accents or the letter ñ) are not allowed.

When should we use it? Whenever the API documentation asks us to send it parameters in this format, using the GET verb. The most modern and practical way is to use the URLSearchParams object.

const URL_API = "https://dominio.com";
const misParametros = new URLSearchParams();
misParametros.set("query", "barcos");
misParametros.set("page", 4);
const URLConParametros = `${URL_API}?${misParametros.toString()}`;

console.log(URLConParametros);
// https://dominio.com?query=barcos&page=4

Don't build the URL by hand! There are characters, like spaces or accents, that you won't be able to concatenate correctly without first parsing them to URI. Use URLSearchParams even if it's just a single parameter.

POST

POST method

Using .then()

fetch('https://jsonplaceholder.typicode.com/users', {
  headers: {
    'Content-type': 'application/json'
  },
  method: 'POST',
  body: JSON.stringify({ id: 11, name: 'Rodrigo Díaz de Vivar', username: 'El Cid' })
  })
  .then(function(response) {
    // Transforms the response. In this case it converts it to JSON
    return response.json();
  })
  .then(function(json) {
    // We use the received information as needed
    console.log(json)
  });

Another version with an arrow function.

fetch('https://jsonplaceholder.typicode.com/users', {
  headers: {
    'Content-type': 'application/json'
  },
  method: 'POST',
  body: JSON.stringify({ id: 11, name: 'Rodrigo Díaz de Vivar', username: 'El Cid' })
  })
  .then((response) => response.json())
  .then((json) => console.log(json));

Using await

async function anyadirUsuario() {
  // Makes the request
  const miFetch = await fetch('https://jsonplaceholder.typicode.com/users', {
  headers: {
    'Content-type': 'application/json'
  },
  method: 'POST',
  body: JSON.stringify({ id: 11, name: 'Rodrigo Díaz de Vivar', username: 'El Cid' })
  });
  // Transforms the response. In this case it converts it to JSON
  const json = await miFetch.json();
  // Log to the console
  console.log(json);
}

anyadirUsuario();

Returning.

{
  "id" : 11,
  "name" : Rodrigo Díaz de Vivar,
  "username" : El Cid
}

PUT

PUT method

Using .then()

fetch('https://jsonplaceholder.typicode.com/users/1', {
  headers: {
    'Content-type': 'application/json'
  },
  method: 'PUT',
  body: JSON.stringify({ username: 'El Campeador' })
  })
  .then(function(response) {
    // Transforms the response. In this case it converts it to JSON
    return response.json();
  })
  .then(function(json) {
    // We use the received information as needed
    console.log(json)
  });

Another version with an arrow function.

fetch('https://jsonplaceholder.typicode.com/users/1', {
  headers: {
    'Content-type': 'application/json'
  },
  method: 'PUT',
  body: JSON.stringify({ username: 'El Campeador' })
  })
  .then((response) => response.json())
  .then((json) => console.log(json));

Using await

async function actualizarUsuario() {
  // Makes the request
  const miFetch = await fetch('https://jsonplaceholder.typicode.com/users/1', {
  headers: {
    'Content-type': 'application/json'
  },
  method: 'PUT',
  body: JSON.stringify({ username: 'El Campeador' })
  });
  // Transforms the response. In this case it converts it to JSON
  const json = await miFetch.json();
  // Log to the console
  console.log(json);
}

actualizarUsuario();

Giving us back the information we've modified.

{
  username: "El Campeador",
  id: 1
}

DELETE

DELETE method

Using .then()

fetch('https://jsonplaceholder.typicode.com/users/2', {
  method: 'DELETE'
  })
  .then(function(response) {
    // Transforms the response. In this case it converts it to JSON
    return response.json();
  })
  .then(function(json) {
    // We use the received information as needed
    console.log(json);
  });

Another version with an arrow function.

fetch('https://jsonplaceholder.typicode.com/users/2', {
  method: 'DELETE'
  })
  .then((response) => response.json())
  .then((json) => console.log(json));

Using await

async function borrarUsuario() {
  // Makes the request
  const miFetch = await fetch('https://jsonplaceholder.typicode.com/users/1', {
  headers: {
    'Content-type': 'application/json'
  },
  method: 'DELETE'
  });
  // Transforms the response. In this case it converts it to JSON
  const json = await miFetch.json();
  // Log to the console
  console.log(json);
}

borrarUsuario();
Activity 1

Use the following API https://yesno.wtf/ so that when a button is clicked it answers us with a Yes or No.

Nightmare level 👹

Show the gif.

Activity 2

Use the following endpoint with the list of Pokemon in order to display all the Pokemon in a table.

Activity 3

Starting from the following URL, try to build a Wikipedia search engine.

https://es.wikipedia.org/w/api.php?action=query&list=search&srsearch=Nelson%20Mandela&utf8=&format=json&origin=*

The most important parameter, and the one you should manipulate, is srsearch, the rest are mandatory

Activity 4

Using the jsonplaceholder API, build a blog using the endpoints:

  • /posts
  • /posts/1
  • /posts/1/comments

Your goals are:

  1. List 5 articles with: title and author.
  2. Create a button to view the next 5.
  3. When an article is clicked, show its text and comments.
  4. Add a search box that finds articles by title or content.

Don't forget to create an elegant loading state to distract readers.

Nightmare level 👹

Create infinite scroll instead of using a button.

Hint: use IntersectionObserver!

Activity 5

Using the Openweathermap API, show me in HTML whether it's going to rain today.

https://openweathermap.org/api

Activity 6

This work is under a Attribution-NonCommercial-NoDerivatives 4.0 International license.

Desafíos de programación atemporales y multiparadigmáticos

Desafíos de programación atemporales y multiparadigmáticos

Te encuentras ante un librillo de actividades, divididas en 2 niveles de dificultad. Te enfrentarás a los casos más comunes que te puedes encontrar en pruebas técnicas o aprender conceptos elementales de programación.

Buy the book

Will you buy me a coffee?

This is how I keep writing without ads or paywalls.

Comments

There are no comments yet.