No tienes acceso a esta clase

隆Contin煤a aprendiendo! 脷nete y comienza a potenciar tu carrera

Fetch data

9/26
Recursos

Aportes 86

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?

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

  • 鈥榥uevo鈥
  • 鈥楨lectronics鈥
  • 鈥楩urniture鈥
  • 鈥楽hoes鈥
  • 鈥極thers鈥

.
La llamada a la API para obtener la categoria, no obtiene la categoria asociada al producto, obtiene el primer tipo de categoria (鈥榥uevo鈥). 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.

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.

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

I don鈥檛 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

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);
        });
    });
});

no entiendo su forma de explicar la verdad

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

No se claven tanto sigan adelante

que feo debi贸 ser dev JavaScript antes de es6

@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.

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

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:

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 馃ケ

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 鈥渇echData鈥 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 鈥渆rror1鈥, 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
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 鈥渢his鈥 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)
    })
  })
})

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, 鈥渇etch鈥 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. 馃懆鈥嶐煉

no ser铆a un callback hell

Uf! Leo mucho lloriqueo en esta clase. Disculpen si les sueno poco emp谩tica, pero al ser de la vieja guardia, estoy acostumbrada siempre a investigar m谩s all谩 de lo que el profe dice. Creo que un poquito de lectura no les caer铆a mal. Y ya si de plano no entienden, muchos en la comunidad platzi te podemos ayudar. Pero eso de andar publicando que se rinden, que es p茅sima la forma en como explica el profe鈥 no s茅, me parecen lloriqueos de milenials. Lo siento si ofend铆 a alguien.

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.

馃し鈥嶁檪锔 Sinceramente, este ejemplo es buen铆simo y yo que quer铆a saltarme esta clase en particular por considerarla desactualizada por utilizar XMLHTTPRequest.

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

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

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"]);
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鈥o s茅 si uno tiene que memorizarse esto o podr铆a copiar el c贸digo cada vez que implemente esto鈥rate 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. 鉁ˋl 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茅 馃槃

Estar铆a bueno que se explique un poco mas el 鈥減ara que鈥 de los pasos

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 鈥榥鈥

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:
鈥淓gg 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: 鈥榬equire 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);
        });
    });
});

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

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

Excelente actualizaci贸n 馃殌馃挴