No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Convierte tus certificados en títulos universitarios en USA

Antes: $249

Currency
$209

Paga en 4 cuotas sin intereses

Paga en 4 cuotas sin intereses
Suscríbete

Termina en:

19 Días
11 Hrs
36 Min
15 Seg

Fetch data

9/26
Recursos

Aportes 91

Preguntas 27

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

Si se les hace complicado entener lo que se vió en la clase les recomiendo documentar el código, ir linea por linea, indagar y consultar que hace cada método, cada función, cada atributo, así es mucho más facil comprender. Les dejo el mio documentado, espero sea de gran ayuda:

const XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest;
const API = "https://api.escuelajs.co/api/v1";

//funcion principal que obtendrá la informacion del producto como un objeto
function fetchData(urlApi, callback) {
    //inicializar un objeto de tipo XMLHttpRequest
    let xhttp = new XMLHttpRequest();
    //El metodo .open realiza la petición de apertura de comunicación, el metodo puede ser 'GET' o 'POST', luego se envia la URL, si es asincrono (true o false), usuario y contraseña. En esta caso solo se utiliza el metodo, la url y async
    xhttp.open('GET', urlApi, true);
    //en este metodo Almacena el nombre de la función que se ejecutará cuando el objeto XMLHttpRequest cambie de estado
    xhttp.onreadystatechange = function (event) {
        //el atributo readyState define el estado del objeto XMLHttpRequest
        //0 No inicializado
        //1 Loading
        //2 ejecutado
        //3 interactuando
        //4 completado
        if (xhttp.readyState === 4) {
            //si la respuesta de la API es exitosa (200 Ok)
            if (xhttp.status === 200) {
                //se ejecuta el callback recibiendo como argumentos un objeto, como la respuesta de la API es un texto plano, el metodo JSON.parse tranformará este texto en un objeto.
                //El atributo devuelve un DOMString que contiene la  respuesta a la consulta como un texto o null si la consulta no tuvo exito o aun no ha sido completada.
                callback(null, JSON.parse(xhttp.responseText));
                //si la respuesta de la API no es exitosa se captura el error
            } else {
                //se inicializa un objeto de tipo Error donde se le envian como argumentos un mensaje de error y la URL de la API para conocer en dónde se produjo el error
                const error = new Error("Error" + urlApi);
                //se ejecuta el callback recibiendo como argumentos el error y null debido a que no se pudo obtener el objeto
                return callback(error, null);
            }
        }
    //el método .send() envia la petición al servidor
  }
  xhttp.send();
}

//se invoca el metodo fetchData() pasandole como argumentos la varible API concatenada con la cadena 'products' para acceder a la URL de la API deseada, y una función anónima que recibe 2 parámetros (un objeto de error y un arreglo que almacena todos los objetos traidos por la API).
fetchData(`${API}/products`, function (error1, data1) {
    //se valida si existe un error, en caso de que exista se detiene el proceso y se imprime el error
    if (error1) return console.error(error1);
    //se invoca nuevamente la función fetchData con el fin de acceder a un objeto puntual del arreglo data1, se envia como parámetros la url de la API apuntando al atributo del primer objeto de arreglo data1 y nuevamente una función anónima.
    fetchData(`${API}/products/${data1[0].id}`, function (error2, data2) {
        //si en este punto se identifica un error se imprime en consola y se detiene el proceso
        if (error2) return console.error(error2);
        //Se invoca nuevamente la funcion fetchData con el fin de acceder a la categoria, se envían como parametros la url de la API con la concatenación de 'Categories' y el atributo Id de categoria del objeto data2 de la función anterior
        //en este caso puntual se hace uso de Optional Caining el cual hace una evalucación de las propiedades de un objeto y en vez de arrojar un error devuelve undefined en caso que la propiedad no exista o sea null.
        //igual que las anteriores e envia una funcion anonima con 2 argumentos, un objeto Error y un objeto de datos
        fetchData(`${API}/categories/${data2?.category?.id}`, function (error3, data3) {
            //se valida si existe error, en caso de que exista se detiene el proceso y se imprime el error
            if (error3) return console.error(error3);
            //Se imprime el objeto en la posición 1 del arreglo de los objetos obtenidos en el metodo invocado inicialmente
            console.log(data1[0]);
            //Se imprime el titulo del objeto que se consultó en la seguna invocación de la función
            console.log(data2.title);
            //Se imprime el nombre de la categoria a la que pertenece el objeto que se consultó en la seguna invocación del método.
            console.log(data3.name);
        });
  });
});

𝗖𝗹𝗮𝘀𝗲 #𝟴: 𝗙𝗲𝘁𝗰𝗵 𝗱𝗮𝘁𝗮 𝟴/𝟮𝟭
.

  • Para evitar la mala práctica de un Call Hell, no es recomendable exceder de 3 callback, para ello se utilizan las promesas o el Async Away.
    .
  • Existen varios tipos de console, dependiendo del navegador, la fuente o el color cambian de acuerdo al tipo (fuente: aquí):
console.info("info"); //muestra un mensaje de información en la consola web
console.error("error"); //muestra mensaje de un error
console.warn("warn"); //muestra mensaje de advertencia
console.log("log"); //para mensajes generales de registro de información

.
Siguiendo con el proyecto:
.
En el archivo challenge.js se agrega el siguiente código:

fetchData(`${API}/products`, function (error1, data1) {
    if (error1) return console.error(error1); //si hay error, devuelve el error
    fetchData (`${API}/products/${data1[0].id}`, function(error2, data2){
        if(error2) return console.error(error2); //valida el error 2
        //se usa Optional chaining '?.' que es una forma segura de acceder a las propiedades de los objetos anidados, incluso si no existe una propiedad intermedia:
        fetchData(`${API}/categories/${data2?.category?.id}`, function(error3, data3){
            if(error3) return console.error(error3);
            //evitar el callback hell
            console.log(data1[0]);
            console.log(data2.title);
            console.log(data3.name);
        });
    });
});
  • Revisar que el código esté bien y seleccionar todo el código del archivo challenge.js y dar en Run Code. Abajo en consola debe salir la información solicitada.


Callback Hell, por eso es recomendable el uso de Async/Await.

Inmejorable la idea de colar un error para explicarnos como buscar en el navegador, como consultar en Stack Overflow. Parece una tontería pero es de una ayuda inmensa que un profesor haga esto en un curso. Felicitaciones.

Este tema es muy complejo, y entiendo que el profe ha ido mejorando en su pedagogía, pero es que es bien difícil entenderle algunas cosas porque no explica bien la razón o la forma en la que un elemento va a ir interactuando con otro.

Me perturba que onreadystatechange no esté en camel case.

No entiendo nada, estas clases son las que me hacen plantearme si voy a ser capaz o no…

Deberían hacer ejercicios mas simples e ir subiendo la complejidad de los mismo de a poco. La verdad es que para una persona que recién esta aprendiendo estos temas, es sumamente complicado.

Yo mira que lo intento con Óscar… pero de verdad no entiendo esa manera de explicar tan técnica en una escuela para APRENDER un lenguaje, pasa absolutamente en todos sus cursos.

Obvio que los programadores tenemos que lidiar con documentación técnica a lo largo de nuestro desempeño profesional, pero esto es un curso de formación y educativo para hacernos mejores profesionales y se debería dar la información de una manera más divulgativa sin perder el componente técnico. Otros profesores de Platzi lo consiguen a la perfección, se me viene a la mente Diego de Granda, o Juan.

Ojalá este mensaje lo lea y lo intente aplicar a sus futuros cursos.

Les comparto el link de un video que me ayudó a entender mejor lo que es Optional Chaining!

https://www.youtube.com/watch?v=K7rHYyf6E0g

Me encanto esta nueva versión 😃

si es necesario aprender XMLHttpRequest, o saltamos directo a las promesas?

Me pareció muy genial que se buscara el error. Obviamente le profe ya sabe porque se debe este error, pero la forma de afrontarlo es como la que deberíamos tener, aceptar que no lo sabemos todo y pedir ayuda.

Hola, solo queria compartirles lo siguiente.
.
Existen 5 categorias de producto:

  • ‘nuevo’
  • ‘Electronics’
  • ‘Furniture’
  • ‘Shoes’
  • ‘Others’

.
La llamada a la API para obtener la categoria, no obtiene la categoria asociada al producto, obtiene el primer tipo de categoria (‘nuevo’). Esto debido a como esta construida la API.
.
Tambien mencionar que para obtener la información no era necesario hacer tantos callbacks, solo con este bloque se podia obtener lo mismo y la categoria real asociada al producto

fetchData(`${API}/products`, function (error, all) {
    if (error) return console.log(error);

    const product = all[0];
    
    console.log(product)
    console.log(product.title)
    console.log(product.category.name)
})

Aunque claro que todo se hizo para illustrar un poco el callback hell y llamadas que podian ser dependientes (o eso creo).
.
Ademas tambien en el manejo de errores, al no ser tan personalizado pues no veo necesario declararlos explicitamente, ya que la misma consola nos los arroja.
.
Yo tambien apenas estoy aprendiendo del tema, asi que cualquier cosa que vean que me equivoco, agradeceria su retroalimentación.

I don’t think this is a good starting point to learn these topics. Asynchronism in JavaScript cannot be learnt just with a basic course completed. You also need to know at least some backend theory just to understand what a request even is. In this classes the professor is just spitting out a lot of information without context and that makes it harder to fully understand what he is doing in code

No me habia topado durante los cursos alguno que tuviera tantos comentarios negativos… Arreglen este curso Platzi

Es claro que el ejemplo tiene como intensión la venja de usar promesas.

No se claven tanto sigan adelante

Bueno, les comento, que me cuesta un poco entender, pero estas dos últimas clases lo que hice fue empezar a tomar apuntes, línea de código por línea de código, y creo que lo estoy entendiendo ya un poco más, estoy segura que con el pasar de las clases y mientras se toma más experiencia, todo será mucho más claro.
Aquí les dejo mis apunte.
En esta clase hacemos el llamado a la función “fechData” que creamos en la clase anterior, pasando como primer parámetro, la constante que creamos con el link de la API, mas el “/productos”, que nos redireccionará hacia la página donde están los productos directamente, como segundo parámetro, ponemos una función anónima, con los parámetro error y data.

Luego creamos un if, pasando el parámetro “error1”, de la función que creamos dentro de nuestro fetch data, y retornamos error, esto hará que nos muestre error si no llega a funcionar la conexión a la API, y nos dirá qué fue lo que falló exactamente.

fetchdata(`${API}/products`, function(error1, data1) {
    if (error1) return console.error(error1);
})

Posterior llamamos la función fetchData, pero como parámetros, pasamos la constante con el link, accedemos a products y adicional a la id de posición 0, de la data1, que pusimos de parámetro en la anterior, y de segundo parámetro una función anónima nuevamente, con los parámetros error2 y data2, con un if por si ocurre un error no lo muestre o si no, que entre al siguiente fetchData que crearemos, pero esta vez entraremos como primer parámetro, al link de la API, pero entramos a categories, y buscaremos en esta el id de la categoría de los productos, dentro del data2, que es la información que obtuvimos en el anterior fetchData (se recomienda incluir el “?”, optional chaining, para evitar el error, por si algún valor no está bien?, ahora como segundo parámetro haremos otra función, pasando error3 como primer parámetro, y el data3, serían 3 peticiones para 3 valores distintos. aquí ya terminaremos este ejercicio para evitar en calbackHell.

fetchdata(`${API}/products`, function(error1, data1) {
    if (error1) return console.error(error1);
fetchdata(`${API}/products/${data1[0].id}`, function(error2, data2) {
        if (error2) return console.log(error2);
        fetchdata(`${API}/categories/${data2?.category?.id}`, function(error3, data3) {
            if (error3) return console.log(error3);
			});
    });
});

Ahora haremos console.log, para obtener la información de los 3 llamados o peticiones (fetchData).

	console.log(data1[0]); // nos dará la información del primer producto de la API
  console.log(data2.title); // Nos da el título del primero producto de la API
  console.log(data3.name); // nos da el nombre de la categoría dentro del primer producto de la API

Aquí todo el código

const XMLHTTpRequest = require('xmlhttprequest').XMLHttpRequest;
const API= 'https://api.escuelajs.co/api/v1';

function fetchdata(urlApi, callback) {
    let xhttp = new XMLHTTpRequest();

    xhttp.open('GET', urlApi, true);
    xhttp.onreadystatechange = function(evento) {
        if (xhttp.readyState ===4){ // 0 no se ha inicializado 1 loading 2 se ejecutó, 3 cargando e interactuando, 4 información completa
            if(xhttp.status === 200){ // 200 correcta
                callback(null, JSON.parse(xhttp.responseText));
            }else {
                const error = new Error('Error' + urlApi);
                return callback(error, null);
        } 
        }
    }
    xhttp.send();
}

fetchdata(`${API}/products`, function(error1, data1) {
    if (error1) return console.error(error1);
    fetchdata(`${API}/products/${data1[0].id}`, function(error2, data2) {
        if (error2) return console.log(error2);
        fetchdata(`${API}/categories/${data2?.category?.id}`, function(error3, data3) {
            if (error3) return console.log(error3);
            console.log(data1[0]); // nos dará la información del primer producto de la API
            console.log(data2.title); // Nos da el título del primero producto de la API
            console.log(data3.name); // nos da el nombre de la categoría dentro del primer producto de la API
        });
    });
});

Finalmente este el resultado que nos da cada console:

console.log(data1[0]); // nos da la información del primer producto de la API
{
  id: 35,
  title: 'Incredible Steel Bacon',
  price: 730,
  description: 'Andy shoes are designed to keeping in mind durability as well as trends, the most stylish range of shoes & sandals',
  category: {
    id: 1,
    name: 'Clothes',
    image: 'https://api.lorem.space/image/fashion?w=640&h=480&r=2981'
  },
  images: [
    'https://api.lorem.space/image/fashion?w=640&h=480&r=4222',
    'https://api.lorem.space/image/fashion?w=640&h=480&r=7355',
    'https://api.lorem.space/image/fashion?w=640&h=480&r=1163'
  ]
}
console.log(data2.title); // Nos da el título del primero producto de la API
Incredible Steel Bacon
console.log(data3.name); // nos da el nombre de la categoría dentro del primer producto de la API
Clothes

no entiendo su forma de explicar la verdad

Si indicas en el package.json type module podras trabajar con import

import { XMLHttpRequest } from "xmlhttprequest";//llamado al XmlHttpRequest
const API = "https://api.escuelajs.co/api/v1";//API en mayúscula porque es una referencia que no va a cambiar

function fetchData(urlApi, callback){
    let xhttp = new XMLHttpRequest(); //referencia a new XMLHttpRequest

    xhttp.open('GET', urlApi, true); //petición "obtener" con true para habilitarlo

    xhttp.onreadystatechange = function(event){ //escucha diferentes estados de la solicitud y conocer cuando está disponible la información
        
        if(xhttp.readyState === 4){ //si el estado ha sido completada la llamada
            if(xhttp.status === 200){ //el servidor responde de forma correcta
                //dentro de xhttp.responseTex recibimos lo que entrega el servidor en texto y se hace la transformación en JSON
                callback(null, JSON.parse(xhttp.responseText)) 
            } else {
                const err = new Error('Error' + urlApi)
                callback(err, null); //es null porque no se está regresando ningún dato
            }
        }
    }

    xhttp.send();
}

fetchData(`${API}/products`, function (error1, data1) {
    if (error1) return console.error(error1); //si hay error, devuelve el error
    fetchData (`${API}/products/${data1[0].id}`, function(error2, data2){
        if(error2) return console.error(error2); //valida el error 2
        //se usa Optional chaining '?.' que es una forma segura de acceder a las propiedades de los objetos anidados, incluso si no existe una propiedad intermedia:
        fetchData(`${API}/categories/${data2?.category?.id}`, function(error3, data3){
            if(error3) return console.error(error3);
            //evitar el callback hell
            console.log(data1[0]);
            console.log(data2.title);
            console.log(data3.name);
        });
    });
});
@PlatziTeam el profesor hace su mejor esfuerzo pero enserio es de los más complicados de todo platzi, somos varios a los que nos parece que no sabe enseñar. Este tipo de temas que ya empiezan a ser complejos deben tener una metodología más amigable, no la explicación de puros conceptos desconectados el uno del otro, y el profesor no ayuda. En mi caso he hecho la ruta en estricto orden, pero todos los cursos que da GDNX son tremendamente complicados, no por el tema, sino por su explicación. No es coincidencia que en casi todas las clases otros estudiantes compartan explicaciones de youtube, que son más fáciles de entender.

que feo debió ser dev JavaScript antes de es6

Para las versiones mas recientes de node podemos cambiar el require() (synchronous):

var XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest;

por el import de este mismo modulo (asynchronous):

import { XMLHttpRequest } from "xmlhttprequest";

Mira más info sobre Require vs Import. Claro, esto producirá un error donde nos dirá:

(node:2172) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
(Use `node --trace-warnings ...` to show where the warning was created)
d:\docu\examples\projectasync\src\callbacks\challenger.js:7
import { XMLHttpRequest } from "xmlhttprequest";
^^^^^^

SyntaxError: Cannot use import statement outside a module

y si leemos la primera linea del Warning nos dice que debemos agregar en nuestro packaje.json

{
  "name": "projectasync",
  "version": "1.0.0",
  "type": "module", //<<=This Line
  ...
}

el resultado:

🤷‍♂️ Sinceramente, este ejemplo es buenísimo y yo que quería saltarme esta clase en particular por considerarla desactualizada por utilizar XMLHTTPRequest.

Lo del optional chaining lo pueden encontrar en el video de ECMAScript 2020
ECMAScript 2020

  • Optional chaining
    • Trabajar con diferentes niveles cuando no existe un key en un objecto
      let developer = {}
      console.log(developer?.country?.name);
      

Analicemos Fetch data paso a paso

Empecemos desde lo básico. En JavaScript, “fetch” es una función que permite hacer solicitudes a servidores web y obtener datos. Es comúnmente utilizada para obtener información de APIs (interfaces de programación de aplicaciones) y mostrar esos datos en una página web.

Analicemos el código de la clase paso a paso:

fetchData(`${API}/products`, function (error1, data1) {
  if (error1) return console.error(error1);
  fetchData(`${API}/products/${data1[0].id}`, function (error2, data2) {
    if (error2) return console.error(error2);
    fetchData(
      `${API}/categories/${data2.category.id}`,
      function (error3, data3) {
        if (error3) return console.error(error3);
        console.log(data1[0]);
        console.log(data2.title);
        console.log(data3.name);
      }
    );
  });
});

En este código, se está utilizando una función fetchData que realiza solicitudes a una API.

  1. Primer Paso:

    fetchData(`${API}/products`, function (error1, data1) {
    

    Aquí, se realiza una solicitud a la URL ${API}/products para obtener datos sobre productos. Se pasa una función como segundo argumento que se ejecutará una vez que se obtengan los datos o si ocurre un error. Esta función toma dos argumentos: error1 y data1.

    Si error1 está presente, significa que hubo un error en la solicitud. En ese caso, se muestra el error en la consola y se sale de la función usando return.

  2. Segundo Paso:

    fetchData(`${API}/products/${data1[0].id}`, function (error2, data2) {
    

    Aquí, se hace otra solicitud para obtener detalles específicos del primer producto que se obtuvo en el paso anterior. Se utiliza data1[0].id para construir la URL. De nuevo, se pasa una función como segundo argumento que se ejecutará después de obtener los datos o en caso de error. Los datos obtenidos se pasan como data2.

    Si hay un error2, se muestra en la consola y se sale de la función.

  3. Tercer Paso:

    fetchData(
      `${API}/categories/${data2.category.id}`,
      function (error3, data3) {
    

    En este paso, se realiza una solicitud para obtener información sobre la categoría del producto obtenido en el paso anterior. Se utiliza data2.category.id para construir la URL de la categoría. Nuevamente, se pasa una función que manejará los datos obtenidos o los errores. Los datos obtenidos se pasan como data3.

    Si hay un error3, se muestra en la consola y se sale de la función.

  4. Últimos Pasos:

    console.log(data1[0]);
    console.log(data2.title);
    console.log(data3.name);
    

    Finalmente, si todas las solicitudes anteriores tuvieron éxito y no hubo errores, se imprimen en la consola diferentes propiedades de los datos obtenidos. En particular, se imprime la información del primer producto (data1[0]), el título del producto (data2.title) y el nombre de la categoría (data3.name).


Este código utiliza un patrón de devolución de llamada (callback) anidado para manejar varias solicitudes en secuencia. Cada solicitud depende de los datos obtenidos de la solicitud anterior. Sin embargo, este patrón puede volverse difícil de mantener a medida que aumenta la complejidad del código. En situaciones más avanzadas, se suelen utilizar enfoques como Promesas o async/await para simplificar y mejorar la legibilidad del código.

Espero sea de utilidad. 👨‍💻

Llevo 6 meses en platzi y es la primera vez que tengo dificultades con un curso, desde que inicio sentía mucha dificultad pero no estaba seguro si solo andaba distraído o que onda.

Los temas en si son dificil de digerir y aparte Oscar le sube mucho la complejidad hablando con muchísimo tecnicismo 😦 Necesitamos otra versión de este curso po favor

Las dos ultimas clases son muy confusas, no da claridad para el aprendizaje 😦

const XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest;
const API = 'https://api.escuelajs.co/api/v1';

function fetchData(urlApi, callback){
    let xhttp = new XMLHttpRequest();

    xhttp.open('GET', urlApi, true)
    xhttp.onreadystatechange = function(event){
        if(xhttp.readyState === 4){
            if(xhttp.status === 200){
                callback(null, JSON.parse(xhttp.responseText));
            } else{
                const error = new Error('Error' + urlApi);
                return callback(error, null);
        } 
        }
    }
    xhttp.send();
}

fetchData(`${API}/products`, function(error1, data1){
    if (error1) return console.error(error1);
    fetchData(`${API}/products/${data1[0].id}`, function(error2, data2){
        if(error2) return console.error(error2);
        fetchData(`${API}/categories/${data2.category.id}`, function(error3, data3){
            if(error3) return console.error(error3);
            console.log(data1[0]);
            console.log(data2.title);
            console.log(data3.name);
        });
    });
});

Me gusto bastante que dijera como era posible solucionar un error y que habia que mira el codigo para ver si habia errores de typing y otro 😄

Leyendo la documentación de w3schools sobre JSON identifique que tiene una opción para que lo transforme en texto y con esto poder mostrarlo de forma de texto en nuestra consola y que no salga como object.

Bendito fetch… jajajaj

Después de muchas horas, de leer la documentación, de probar, de ya haber visto el anterior curso, ver otros videos, al fin creo haber entendido 🥱

const XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest;

// API con la variable
const API = 'https://api.escuelajs.co/api/v1';


function fetchData(urlApi, infoReturnData){
    let xhttp = new XMLHttpRequest();

    xhttp.open('GET', urlApi, true);
    xhttp.onreadystatechange = function(event){
        if (xhttp.readyState === 4){
            if(xhttp.status === 200){ 
                // pasamos el callback
                infoReturnData(null, JSON.parse(xhttp.responseText));
            }  else{
                const error = new Error('Esto es un Error' + urlApi);
                return infoReturnData(error, null);
            }
        }
    }

    // hacemos el llamado al xhttp.send
    xhttp.send();
}


// -------------------------------------------------------------------------------
// Fetch Data

// Vamos a llamar a productos
fetchData(`${API}/products`, (error1, data1) => {
    if (error1) return console.error(error1);
    
    // Products para obtenerlos todos
    fetchData(`${API}/products/${data1[0].id}`, (error2, data2) => {
        if (error2) return console.log(error2);

        fetchData(`${API}/categories/${data2?.category?.id}`, (error3, data3) => {
            if (error3) return console.error(error3);
            console.log(data1[0]);
            console.log(data2.title);
            console.log(data3.name);

        });
    });
});

en esta paguina pude entender muchos de los conceptos utilizados en el codigo link

Tambien podemos usar “this” para xhttp ya que esta dentro del contexto

const XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest;
const API = 'https://api.escuelajs.co/api/v1';

function fetchData(urlApi, callback) {
  const xhttp = new XMLHttpRequest()
  xhttp.open('GET', urlApi, true)
  xhttp.onreadystatechange = function () {
    if (this.readyState === 4) {
      if (this.status === 200) {
        callback(null, JSON.parse(this.responseText))
      } else {
        const error = new Error('Error' + urlApi)
        return callback(error, null)
      }
    }
  }
  xhttp.send()
}

fetchData(`${API}/products`, function(error1, data1) {
  if(error1) return console.error(error1)
  fetchData(`${API}/products/${data1[0].id}`, function(error2, data2) {
    if(error2) return console.error(error2)
    fetchData(`${API}/categories/${data2?.category?.id}`, function(error3, data3) {
      if(error3) return console.error(error3)
      console.log(data1[0])
      console.log(data2.title)
      console.log(data3.name)
    })
  })
})

Estaría bueno que se explique un poco mas el “para que” de los pasos

Para aquellos que consumen su API por primera vez, recomiendo este vídeo de Carlos Azaustre que condensa el método con XMLHttpResponse y Fetch: CÓMO CONSUMIR UN API con JAVASCRIPT desde la web

no sería un callback hell

Los errores son nuestros amigos y nos dicen lo que puede estar pasando, toca analizar la situación.

Para poder entender de mejor manera lo acá explicado, recomiendo mucho tomar el curso de POO y POO intermedio con JavaScript de platzi, permite entender varias cosas que se usan acá, como los métodos usados en las peticiones y la recursividad con las funciones.

PUFF
PESIMA EXPLICACIÓN
Siempre salgo insatisfecho con las explicaciones de este profesor

No le entendí nada. 😕

También habríamos podido traer los datos con el primer callBack, de la siguiente manera:

	    //mostramos los datos consultados
            console.log(data1[0]);
            console.log(data1[0]["title"]);
            console.log(data1[0]["category"]["name"]);
yo al estar realizando el curso me encuentro con que el link <https://api.escuelajs.co/api/v1> no existe
Aguante Fetch() no mas..
curso potente
Lo tuve que hacer como 10 veces y pedirle que me explique el tema al chat gpt como 5 pero le llegue ya
Con las funciones async y await, se puede simplificar ese codigo. Tiene mas lineas pero en visibilidad, es mas legible.async function fetchData(urlAPI) {    return new Promise((resolve, reject) => {        const xhr = new XMLHttpRequest();        xhr.open('GET', urlAPI, true);        xhr.onreadystatechange = () => {            if (xhr.readyState === 4) {                if (xhr.status === 200) {                    resolve(JSON.parse(xhr.responseText));                } else {                    reject(new Error('Error en la solicitud'));                }            }        };        xhr.send();    });} async function getProductData() {    try {        const data1 = await fetchData(`${API}/products`);        console.log(data1\[0]);        const data2 = await fetchData(`${API}/products/${data1\[0].id}`);        console.log(data2.title);        const data3 = await fetchData(`${API}/categories/${data2?.category?.id}`);        console.log(data3.name);    } catch (error) {        console.error(error);    }} ```js async function fetchData(urlAPI) { return new Promise((resolve, reject) => { const xhr = new XMLHttpRequest(); xhr.open('GET', urlAPI, true); xhr.onreadystatechange = () => { if (xhr.readyState === 4) { if (xhr.status === 200) { resolve(JSON.parse(xhr.responseText)); } else { reject(new Error('Error en la solicitud')); } } }; xhr.send(); }); } async function getProductData() { try { const data1 = await fetchData(`${API}/products`); console.log(data1[0]); const data2 = await fetchData(`${API}/products/${data1[0].id}`); console.log(data2.title); const data3 = await fetchData(`${API}/categories/${data2?.category?.id}`); console.log(data3.name); } catch (error) { console.error(error); } } ```
todo correcto les invito a investigar por su propia cuenta, saludos :D
Tengo 1 año conociendo JavaScript, había usado el fetch, pero no entiendo este curso, espero no desanimarme. No entiendo al profesor, no se si es que es muy avanzado para mi.
![](https://static.platzi.com/media/user_upload/code1-51e06538-0e85-44c1-a229-4103ef3495fb.jpg)
Me exaspera tanto rodeo! Ana Belisa Style...
¡Gracias Oscar, esto tiene mucho de lidiar con la frustración y esta fue una semana particularmente difícil, la naturalidad y sencillez con que abordaste el error me hizo reflexionar y tomar aire para seguir!
alguien me podria orientar porque me sale este error, gracias. ![]()Error: Errorhttps://api.escuelajs.co/api/v1/categories/5} at xhttp.onreadystatechange (/Users/ereza/Desktop/developer/curso-asincronismo/src/callback/tempCodeRunnerFile.js:13:31) at exports.XMLHttpRequest.dispatchEvent (/Users/ereza/Desktop/developer/curso-asincronismo/node\_modules/xmlhttprequest/lib/XMLHttpRequest.js:591:25) at setState (/Users/ereza/Desktop/developer/curso-asincronismo/node\_modules/xmlhttprequest/lib/XMLHttpRequest.js:610:14) at IncomingMessage.\<anonymous> (/Users/ereza/Desktop/developer/curso-asincronismo/node\_modules/xmlhttprequest/lib/XMLHttpRequest.js:447:13) at IncomingMessage.emit (node:events:531:35) at endReadableNT (node:internal/streams/readable:1696:12) at process.processTicksAndRejections (node:internal/process/task\_queues:82:21)![](<Captura de Pantalla 2024-02-16 a la(s) 12.41.07>)![](<Captura de Pantalla 2024-02-16 a la(s) 12.41.07>)
A mi no me aparece nada a la hora de ejecutarlo. Qué estoy haciendo mal?![]()![](<Screenshot 2024-02-08 at 9.32.04 AM>)![](https://static.platzi.com/media/user_upload/Screenshot%202024-02-08%20at%209.32.04%20AM-491633e1-0c0e-4e76-8ba2-833b6ab95f3d.jpg) ![](https://static.platzi.com/media/user_upload/Screenshot%202024-02-08%20at%209.34.31%20AM-80670e33-7409-44ac-a8af-f46e4ddaab3e.jpg)
Hola a todos!! Una pregunta, el link de la API expirò? O cambio? Porque a mi me muestra un error a la hora de ejecutarse el codigo, con respecto al link de la API. A alguien mas le ha pasado? De antemano, muchas gracias por sus respuestas!
Estos cursos son perfectos para aprender a profundidad, la primera vez que trabaje consumiendo apis lo hacia con ajax o con axios, librerias que facilitan el trabajo, pero ver la complejidad de xhttp es increible, te ayuda a comprender a más profundidad, y recuerden aunque al principio es confuso aprender de esta manera te da unas bases y unas habilidades de competencia muy grandes para el futuro. Lo facil y rapido no simpre es lo mejor.
venia facil el curso hasta aca. Esto ya es más profesional

Estoy siguiendo la ruta tal cual y si bien entendí la lógica como tal del código de JS, hay bastantes cosas nuevas que me imagino son inherentes al uso de APIs, sin embargo, después de este curso me falta hacer los 4 de APIs, pues hasta el momento se ha nombrado el tema pero nunca lo he usado, así que seguiré con el curso y la ruta y espero luego volver aquí y ya entender al 100%

Cuando vi esta clase por primera vez fue hace como 3 meses, para ese momento no entendi nada y supe que tenia que seguir la ruta de JS a profundidad. Ahora vengo depues de hacer toda la ruta de HTML, CSS y Js y comprendo lo importante que es seguir estas rutas. Ahora lo entiendo todo con claridad xd.

SyntaxError: Unexpected token ‘.’


Si alguien más tuvo el siguiente error:

`${API}/categories/${data2?.categories?.id}`,
                           ^

SyntaxError: Unexpected token '.'

Lo solucione de la siguiente manera:

`${API}/categories/${data2(category.id)}`

Y ahora si me arroja el resultado esperado, o al menos no me tira ese error. Lo que me arroja el run es lo siguiente:

{
  id: 99,
  title: 'Fantastic Soft Chips',
  price: 795,
  description: 'The beautiful range of Apple Naturalé that has an exciting mix of natural ingredients. With the Goodness of 100% Natural Ingredients',
  images: [
    'https://picsum.photos/640/640?r=3437',
    'https://picsum.photos/640/640?r=576',
    'https://picsum.photos/640/640?r=7792'
  ],
  creationAt: '2023-08-31T00:59:30.000Z',
  updatedAt: '2023-08-31T00:59:30.000Z',
  category: {
    id: 5,
    name: 'Others',
    image: 'https://picsum.photos/640/640?r=5649',
    creationAt: '2023-08-31T00:59:30.000Z',
    updatedAt: '2023-08-31T00:59:30.000Z'
  }
}
Fantastic Soft Chips
Others

Espero que sea de ayuda, me estaba molestando este error y se me ocurrió hacer esto.

Es muy largo el proceso…no sé si uno tiene que memorizarse esto o podría copiar el código cada vez que implemente esto…trate de documentar mi code, espero este bien y si es así, que les pueda servir.

//Primero inicializar npm con "npm init"
//Luego instalar el paquete xmlhttprequest con el comando "npm i xmlhttprequest"

const XMLHttppRequest = require('xmlhttprequest'); //llamado al XmlHttpRequest
const API = 'https://api.escuelajs.co/api/v1'; //API en mayúscula porque es una referencia que no va a cambiar //la url es la api fake de Platzi

function fetchData(urlApi, callback) { //urlApi: no confundir y no colocar API
    let xhttp = new XMLHttppRequest(); //referencia a new XMLHttpRequest

    xhttp.open('GET', urlApi, true); //petición "obtener" con true para habilitarlo
    xhttp.onreadystatechange = function (event) { //escucha diferentes estados de la solicitud y conocer cuando está disponible la información
        if (xhttp.readyState === 4) { //si el estado de la petición es COMPLETADO
            if (xhttp.status === 200) { //el estado de respuesta de la petición por parte del servidor fue procesada correctamente
                callback(null, JSON.parse(xhttp.responseText)); //siempre recibe dos parámetros: uno en caso halla un error pero como se verifica en los if que no habrá error, se deja como "null" y el segundo es que dentro de xhttp.responseText recibimos lo que entrega el servidor en texto y se hace la transformación en JSON para poder controlar los datos
            }
        } else {
            const error = new Error('Error' + urlApi);
            return callback(error, null); //en este caso el primer parámetro es el error y el segundo es "null" porque no se está regresando ningún dato
        }
    }
    xhttp.send();
}

fetchData(`${API}/products`, function (error1, data1) { //se quiere obtener los productos del api
    if (error1) return console.error(error1); //se valida si hay un error
    fetchData(`${API}/products/${data1[0].id}`, function (error2, data2) { //en caso no hay error, se vuelve a llamar a la misma función para obtener el primer id del primer producto de la lista obtenida en la primera petición
        if (error2) return console.error(error2); //se valida si hay un error
        fetchData(`${API}/categories/${data2?.category?.id}`, function (error3, data3) { //optional chaining ?. para evitar que el programa colapse hasta que lleguen los datos y si es que no llega devuelve undefined //en caso no hay error, se vuelve a llamar a la misma función para obtener la categoría del producto tomando el id del producto obtenido en la segunda petición
            if (error3) return console.error(error3);//se valida si hay un error
            console.log(data1[0]); //finaliza los callbacks y devuelve estos datos
            console.log(data2.title);
            console.log(data3.name);
        });
    });
});

Recomiendo para entender mejor la clase, estudiar bien el recurso fakeapi.platzi en especial el response que se obtiene, segun el request realizado, para poder entender porque el profe escribe cosas como:

{data1[0].id} 
{data2.category.id} 

la verdad no se explica muy bien, y me costo entender en un principio.

Espero sea de ayuda!

axios simplica los llamados API

9. Fetch data

Esta es una explicación de lo que entendí. Falta pulir detalles pero espero sirva de algo. ✨Al final dejo una forma de hacer lo mismo pero mas sencilla.

Código de la clase

const XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest;
const API = 'https://api.escuelajs.co/api/v1';

function fetchData(urlApi, callback) {
	let xhttp = new XMLHttpRequest();

	xhttp.open('GET', urlApi, true);
	xhttp.onreadystatechange = function (event) {
		if (xhttp.readyState === 4) {
			if (xhttp.status == 200) {
				// Puedes quitarle el JSON.parse para ver como viene toda la información (DOMString cadena de caracteres)
				callback(null, JSON.parse(xhttp.responseText));
			} else {
				const error = new Error('Error en ', urlApi);
				callback(error, null);
			}
		}
	}

	xhttp.send();
}


// Template strings y Optional chaining '?.'
fetchData(`${API}/products`, function (error1, data1) { 👈👀
	if (error1) return console.error(error1);

	fetchData(`${API}/products/${data1[0].id}`, function (error2, data2) {
		if (error2) return console.error(error2);
		
		fetchData(`${API}/categories/${data2?.category?.id}`, function (error3, data3) {
			if (error3) return console.error(error3);
			
			console.log(data1[0]);
			console.log(data2.title);
			console.log(data3.name);
		});
	});
});

// Obtenemos: 
{
  id: 2,
  title: 'Oriental Bronze Car',
  price: 342,
  description: "Boston's most advanced compression wear technology increases muscle oxygenation, stabilizes active muscles",
  images: [
    'https://picsum.photos/640/640?r=2863',
    'https://picsum.photos/640/640?r=4222',
    'https://picsum.photos/640/640?r=3311'
  ],
  creationAt: '2023-07-16T06:10:35.000Z',
  updatedAt: '2023-07-16T06:10:35.000Z',
  category: {
    id: 3,
    name: 'Furniture',
    image: 'https://picsum.photos/640/640?r=2068',
    creationAt: '2023-07-16T06:10:35.000Z',
    updatedAt: '2023-07-16T06:10:35.000Z'
  }
}
Oriental Bronze Car
Furniture

¿Cómo llegamos a ese resultado?

Ya vimos lo que obtenemos como resultado final, pero, ¿Cómo llegamos a ese resultado?

  1. En el primer fetchData obtenemos un array enorme con muchos objetos dentro:
fetchData(`${API}/products`, function (error1, data1) {
	if (error1) return console.error(error1);
	console.log(data1);
});

// Obtenemos esto y más:  
[
  {
    id: 2,
    title: 'Oriental Bronze Car',
    price: 342,
    description: "Boston's most advanced compression wear technology increases muscle oxygenation, stabilizes active muscles",
    images: [
      'https://picsum.photos/640/640?r=2863',
      'https://picsum.photos/640/640?r=4222',
      'https://picsum.photos/640/640?r=3311'
    ],
    creationAt: '2023-07-16T06:10:35.000Z',
    updatedAt: '2023-07-16T06:10:35.000Z',
    category: {
      id: 3,
      name: 'Furniture',
      image: 'https://picsum.photos/640/640?r=2068',
      creationAt: '2023-07-16T06:10:35.000Z',
      updatedAt: '2023-07-16T06:10:35.000Z'
    }
  },
  {
    id: 4,
    title: 'Tasty Frozen Table',
    price: 962,
    description: 'Andy shoes are designed to keeping in mind durability as well as trends, the most stylish range of shoes & sandals',
    images: [
      'https://picsum.photos/640/640?r=7246',
      'https://picsum.photos/640/640?r=9914',
      'https://picsum.photos/640/640?r=1496'
    ],
    creationAt: '2023-07-16T06:10:35.000Z',
    updatedAt: '2023-07-16T06:10:35.000Z',
    category: {
      id: 4,
      name: 'Shoes',
      image: 'https://picsum.photos/640/640?r=260',
      creationAt: '2023-07-16T06:10:35.000Z',
      updatedAt: '2023-07-16T06:10:35.000Z'
    }
  },
  ...
    {
    id: 102,
    title: 'Awesome Granite Bacon',
    price: 1,
    description: 'New ABC 13 9370, 13.3, 5th Gen CoreA5-8250U, 8GB RAM, 256GB SSD, power UHD Graphics, OS 10 Home, OS Office A & J 2016',
    images: [
      'https://picsum.photos/640/640?r=4809',
      'https://picsum.photos/640/640?r=8923',
      'https://picsum.photos/640/640?r=8980'
    ],
    creationAt: '2023-07-16T06:10:35.000Z',
    updatedAt: '2023-07-16T06:10:35.000Z',
    category: {
      id: 2,
      name: 'Electronics',
      image: 'https://picsum.photos/640/640?r=4582',
      creationAt: '2023-07-16T06:10:35.000Z',
      updatedAt: '2023-07-16T06:10:35.000Z'
    }
  }
  ... 100 more items
  1. En el segundo fetchData obtenemos solo el primer objeto y extraemos el title usando console.log(data2.title);:
fetchData(`${API}/products`, function (error1, data1) {
	if (error1) return console.error(error1);
	/* console.log(data1); */

	fetchData(`${API}/products/${data1[0].id}`, function(error2, data2){
		if(error2) return console.error(error2);
		console.log(data2);
	});
});

// Obtenemos el objeto de la posición [0], lo que no logro entender es el porqué le agregan un .id, ya que, sin eso no funciona :v
{
  id: 2,
  title: 'Oriental Bronze Car', 👈👀
  price: 342,
  description: "Boston's most advanced compression wear technology increases muscle oxygenation, stabilizes active muscles",
  images: [
    'https://picsum.photos/640/640?r=2863',
    'https://picsum.photos/640/640?r=4222',
    'https://picsum.photos/640/640?r=3311'
  ],
  creationAt: '2023-07-16T06:10:35.000Z',
  updatedAt: '2023-07-16T06:10:35.000Z',
  category: {
    id: 3,
    name: 'Furniture',
    image: 'https://picsum.photos/640/640?r=2068',
    creationAt: '2023-07-16T06:10:35.000Z',
    updatedAt: '2023-07-16T06:10:35.000Z'
  }
}
  1. En el tercer fetchData buscamos a qué categoría pertenece el producto que obtuvimos anteriormente, pero primero veamos las categorías existentes… :
fetchData(`${API}/products`, function (error1, data1) {
	if (error1) return console.error(error1);
	/* console.log(data1); */

	fetchData(`${API}/products/${data1[0].id}`, function(error2, data2){
		if(error2) return console.error(error2);
		/* console.log(data2); */

		fetchData(`${API}/categories/`, function (error3, data3){
			if(error3) return console.error(error3);
			console.log(data3);
		});
	});
});

// Obtenemos: 
[
  {
    id: 1,
    name: 'Clothes',
    image: 'https://picsum.photos/640/640?r=193',
    creationAt: '2023-07-16T06:10:35.000Z',
    updatedAt: '2023-07-16T06:10:35.000Z'
  },
  {
    id: 2,
    name: 'Electronics',
    image: 'https://picsum.photos/640/640?r=4582',
    creationAt: '2023-07-16T06:10:35.000Z',
    updatedAt: '2023-07-16T06:10:35.000Z'
  },
  {
    id: 3,
    name: 'Furniture', 👈👀 // Esto es lo que necesitamos
    image: 'https://picsum.photos/640/640?r=2068',
    creationAt: '2023-07-16T06:10:35.000Z',
    updatedAt: '2023-07-16T06:10:35.000Z'
  },
  {
    id: 4,
    name: 'Shoes',
    image: 'https://picsum.photos/640/640?r=260',
    creationAt: '2023-07-16T06:10:35.000Z',
    updatedAt: '2023-07-16T06:10:35.000Z'
  },
  {
    id: 5,
    name: 'Others',
    image: 'https://picsum.photos/640/640?r=5088',
    creationAt: '2023-07-16T06:10:35.000Z',
    updatedAt: '2023-07-16T06:10:35.000Z'
  },
  {
    id: 32,
    name: 'New Category',
    image: 'https://placeimg.com/640/480/any',
    creationAt: '2023-07-16T23:28:51.000Z',
    updatedAt: '2023-07-16T23:28:51.000Z'
  },
  {
    id: 33,
    name: 'New Category',
    image: 'https://placeimg.com/640/480/any',
    creationAt: '2023-07-16T23:31:07.000Z',
    updatedAt: '2023-07-16T23:31:07.000Z'
  }
]

Ahora filtremos la categoría de nuestro producto, para lo cual concatenamos el ID que debe buscar ${API}/categories/${data2?.category?.id}, con esto a través de los datos del producto obtenidos en data2 entramos a producto.categoria.id que si nos fijamos es igual a 3. Usando console.log(data3.name); podemos tener el nombre de la categoría a la que pertenece nuestro producto:

fetchData(`${API}/products`, function (error1, data1) {
	if (error1) return console.error(error1);
	/* console.log(data1); */

	fetchData(`${API}/products/${data1[0].id}`, function(error2, data2){
		if(error2) return console.error(error2);
		/* console.log(data2); */

		fetchData(`${API}/categories/${data2?.category?.id}`, function (error3, data3){
			if(error3) return console.error(error3);
			console.log(data3);
		});
	});
});

// Obtenemos 
{
  id: 3,
  name: 'Furniture',👈👀 // Fin 
  image: 'https://picsum.photos/640/640?r=2068',
  creationAt: '2023-07-16T06:10:35.000Z',
  updatedAt: '2023-07-16T06:10:35.000Z'
}

Otra forma

✨ Esta es otra forma de hacer lo mismo, pero más sencilla de entender.

fetchData(`${API}/products`, function (error, all) {
    if (error) return console.log(error);

    const product = all[0];

	/* console.log(all); */ //👈👀 Muestra un array de objetos
	console.log(product);
    console.log(product.title)
    console.log(product.category.name)
})

🔥 Aquí puedes ver más apuntes.

Me ha parecido interesante, me cuesta un poco entenderlo, pero estudiaré 😄

La API Fetch proporciona una interfaz JavaScript para acceder y manipular partes del canal HTTP, tales como peticiones y respuestas.

Se me cayó un ídolo por la utilización de stack overflow.

No me ha gustado este curso, debería de tener mejor documentación. Y debería ser mas didáctico.

Hola,
si les sale un error por los ‘?’ en esta parte del código

${API}/categories/${data2?.category?.id 

no se preocupen.

El error tiene que ver con la versión de node que estamos usando, para que me funcionara instalé la herramienta ‘n’

Este es el comando

npm install -g n

es posible que en algunos ambientes necesites ejecutar con sudo para que tenga permisos de escribir en carpetas de sistema.

El error también se puede solucionar importando el módulo de la siguiente manera:

import { XMLHttpRequest } from "xmlhttprequest";

9/26 Fetch data
Imaginense en unos años cuando dominen este tema y se digan:
“Egg yo si me complicaba la vida por esto tan sencillo” xD

const XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest;
const API = 'https://api.escuelajs.co/api/v1';

function fetchData(urlApi, callback) {
  let xhttp = new XMLHttpRequest();

  xhttp.open('GET', urlApi, true);
  xhttp.onreadystatechange = function (event) {
    if (xhttp.readyState === 4) {
      if (xhttp.status === 200) {
        callback(null, JSON.parse(xhttp.responseText));
      } else {
        const error = new Error('Error' + urlApi);
        return callback(error, null);
      }
    }
  }
  xhttp.send();
}

fetchData(`${API}/products`, function (error1, data1) {
  if (error1) return console.error(error1);
  fetchData(`${API}/products/${data1[0].id}`, function (error2, data2) {
    if (error2) return console.error(error2);
    fetchData(`${API}/categories/${data2?.category?.id}`, function (error3, data3) {
      if (error3) return console.error(error3);
      console.log(data1[0]);
      console.log(data2.title);
      console.log(data3.name);
    });
  });
});

el profesor explica muy mal, muchas vueltas

🍃 aqui la segunda parte del código comentado.

// Se llama a la función 'fectchData' para obtener los productos de la API
fectchData(`${API}/products`, function (error1, data1) {
	// Si hay un error, se muestra en la consola
	if (error1) return console.error(error1);

	// Se llama a la función 'fectchData' para obtener los detalles del primer producto de la API
	fectchData(`${API}/products/${data1[0].id}`, function (error2, data2) {
		// Si hay un error, se muestra en la consola
		if (error2) return console.error(error2);

		// Se llama a la función 'fectchData' para obtener los detalles de la categoría del producto
		fectchData(
			`${API}/categories/${data2?.category.id}`,
			function (error3, data3) {
				// Si hay un error, se muestra en la consola
				if (error3) return console.error(error3);

				// Se imprime en la consola los detalles del primer producto
				console.log(data1[0]);

				// Se imprime en la consola el título del producto
				console.log(data2.title);

				// Se imprime en la consola el nombre de la categoría del producto
				console.log(data3.name);
			}
		);
	});
});

Me gusto el detalle de que el profesor usa StackOverflow en esto, no se si fue intensional o no pero fue un gran detalle como no cae en que el programador tiene que casi saberse la documentacion de memoria, muy buena clase, me gusto.

Vi innecesario el código ya que se produce un callback hell (muchas llamadas a callbacks, cómo código spaghetti) entonces lo que hice fue:

function fetchData(url, callback){
    peticion.open('GET', url);
    peticion.onreadystatechange = ()=>{
        if(peticion.readyState === 4){
            if(peticion.status === 200){
                callback(null, JSON.parse(peticion.responseText));
            }
        }else{
            const error = new Error('Error en la llamada a: ' + url);
            return callback(error, null);
        }
    }
    
    peticion.send();
}

fetchData(API, (error, data)=>{
    if(error) console.error(error);
    else console.log(data.map(item => item.title));
})

Para practicar retorné un array con los titulos de cada producto

Me salió el siguiente error: ‘require is not defined in ES module scope’ y despues de averiguar el error me encontre con este video (link) espero les ayude si tienen el mismo error.

¡Un abrazo!

Si estas en esta parte del curso, quiero informarte que tenemos problemas con el API, repito tenemos problemas con el API Houston !

Qué vaina tan confusa y difícil, no creo que vaya a poder con esto… Me rindo.

El codigo no funcionaba, tenia algunos typos… Los corregi pero tampoco devolvia el response esperado. Parece que hay algun problema con la FakeAPI

Apunte en Notion

Tuve un problema y encontré dos soluciones.

El problema era que me daba requiere is not
O algo así:

ReferenceError: require is not defined in ES module scope, you can use import instead
This file is being treated as an ES module because it has a '.js' file extension and '/home/pogolo/CLASES/Asincronismo_curso/package.json' contains "type": "module". To treat it as a CommonJS script, rename it to use the '.cjs' file extension.

Primera opción

En package.json tengo escrito esto hasta el final

  },
  "type": "module"
}

  • y para que el proyecto funcione le tengo que agregar un c a la extensión.
    O sea:
mine.js => mine.cjs

Y ya funciona!

Segundo opción

  • La parte superior del archivo tiene que cambiar

De esto (bad):

const XMLHttppRequest = require('xmlhttprequest').XMLHttpRequest; 
const API = 'https://api.escuelajs.co/api/v1'; 

function fetchData(urlApi, callback){  
	let xhttp = new XMLHttppRequest();

A esto (good):

import { XMLHttpRequest } from "xmlhttprequest";
const API = 'https://api.escuelajs.co/api/v1'; 

function fetchData(urlApi, callback) { 
    let xhttp = new XMLHttpRequest(); 

Nota que lo que cambia.

Las letras chiquitas:
Me siguió dando unos errores, pero ya me daba información :p

yo para poder seguir con las clases de ES6 en la ruta de JS, tuve que parar, irme a la ruta de WEB y ver muchos cursos de JS basico, para poder entender estas clases, entiendo lo que dicen los compañeros, pero animo que, si se puede y GNDX sabe un monton, aprovechen el recurso como puedan.


Por ahi les dejo video para que podamos entender mas a fondo el optional chaining.

si por algun motivo, al ejecutar el programa con code runner, les sale el error de:

ReferenceError: require is not defined in ES module scope, you can use import instead 

Por lo menos en mi caso, actualize tanto npm y node tambien. Despues de eso, el codigo me funciono normal. aqui dejo los enlaces, de como actualize npm y node.
https://phoenixnap.com/kb/update-node-js-version

Recapitulation: we have our archeve of challenge, we are revolving the cahllend call APIPlatzi, this bring information same about the Ecomerce.
We want bring all products, call a product, then call category pertenecent and show this information.

// variable in capital letter is a valor no change in our files
const XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest;
const API = 'https://api.escuelajs.co/api/v1';

// callback is info return the elements or error
function fetchData(urlAPI, callback) {
    let xhttp = new XMLHttpRequest();

    xhttp.open('GET', urlAPI, true);
    xhttp.onreadystatechange  = (event) => {
        if (xhttp.readyState === 4) { // 4 is a state - 0 is not initial - 1 - loading - 2 execute send - 3 interacting - 4 completed call
            if (xhttp.status === 200) { // 200 is request is correct
                callback(null, JSON.parse(xhttp.responseText));
            } else {
                const error = new Error('ERROR' + urlApi);
                return callback(error, null);
            }
        } 
    }
    xhttp.send();
}

// Principal function for do the call

// --

// pass him the variable base the we API
// (/) for go to the products petition
// anonymous function  
fetchData(`${API}/products`, (error1, data1) =>  {
    // if send error for logic stop 
    if ( error1 ) return console.error(error1);
    // is invoked fetchData() for access a punctual object the array data1 
    fetchData (`${API}/products/${data1[0].id}`, (error2, data2) => {
        if( error2 ) return console.error(error2);
        fetchData (`${API}/categories/${data2?.category?.id}`, (error3, data3) => { // nest levels
            if (error3) return console.error(error3);
            console.log(data1[0]);
            console.log(data2.title);
            console.log(data3.name);
        });
    });
});

callback hell a la vista, esta bien conocer como se hacia antes, pero es mas entendible con fetch(…mycode).then()

Excelente actualización 🚀💯