Handle same request multiple times

I'm building a silly music quiz game for learning. I need to populate my view with related music from deezer api.

What I need:

  1. Get a random genre
  2. Get 5 artist from this genre (id + name)
  3. Get 1 music from each artist (name + link preview)

So, I found my way until step 3

But I can't find out how to properly send the same request 4 times (for each artist), and my reasearch gave me nothing so far

function deezer() { const reqGenero = new Request('); fetch(reqGenero) .then(response => { if (response.status === 200) { return response.json(); } else { throw new Error('Erro ao pegar gêneros'); } }) .then(generos => { /* pega genero aleatorio */ var generoId = generos.data[Math.floor(Math.random() * 10 + 1)].id; //console.log('\ngenero... ' + generoId); return fetch(' + generoId + '/artists') }) .then(response => { if (response.status === 200) { return response.json(); } else { throw new Error('Erro ao pegar artistas'); } }) .then(artistas => { /* 1 música de 4 artistas */ var artistasIds = []; for(var i = 0; i <= 4; i++) { artistasIds.push(artistas.data[i].id); console.log('\nId: ' + artistasIds[i]); // CAN I SEND THIS REQUEST 4 TIMES? return fetch(' + ids + '/top'); } }) .catch(error => { console.error(error); }); } 

*Pleade let me know if I'm doing something really wrong

4 Answers

If using promises explicitly (see below for async functions), I'd probably approach it like this; see *** comments for explanation:

// *** Give yourself a helper function so you don't repeat this logic over and over function fetchJson(errmsg, ...args) { return fetch(...args) .then(response => { if (!response.ok) { // *** .ok is simpler than .status == 200 throw new Error(errmsg); } return response.json(); }); } function deezer() { // *** Not sure why you're using Request here? const reqGenero = new Request('); fetchJson('Erro ao pegar gêneros', reqGenero) .then(generos => { /* pega genero aleatorio */ var generoId = generos.data[Math.floor(Math.random() * 10 + 1)].id; //console.log('\ngenero... ' + generoId); return fetchJson('Erro ao pegar artistas', ' + generoId + '/artists') }) .then(artistas => { /* 1 música de 4 artistas */ // *** Use Promise.all to wait for the four responses return Promise.all(artistas.data.slice(0, 4).map( entry => fetchJson('Erro ao pegar música', ' + entry.id + '/top') )); }) .then(musica => { // *** Use musica here, it's an array of the music responses }) .catch(error => { console.error(error); }); } 

That's assuming you want to use the results in deezer. If you want deezer to return the results (a promise of the four songs), then:

// *** Give yourself a helper function so you don't repeat this logic over and over function fetchJson(errmsg, ...args) { return fetch(...args) .then(response => { if (!response.ok) { // *** .ok is simpler than .status == 200 throw new Error(errmsg); } return response.json(); }); } function deezer() { const reqGenero = new Request('); return fetchJson('Erro ao pegar gêneros', reqGenero) // *** Note the return .then(generos => { /* pega genero aleatorio */ var generoId = generos.data[Math.floor(Math.random() * 10 + 1)].id; //console.log('\ngenero... ' + generoId); return fetchJson('Erro ao pegar artistas', ' + generoId + '/artists') }) .then(artistas => { /* 1 música de 4 artistas */ // *** Use Promise.all to wait for the four responses return Promise.all(artistas.data.slice(0, 4).map( entry => fetchJson('Erro ao pegar música', ' + entry.id + '/top') )); }); // *** No `then` using the results here, no `catch`; let the caller handle it } 

The async function version of that second one:

// *** Give yourself a helper function so you don't repeat this logic over and over async function fetchJson(errmsg, ...args) { const response = await fetch(...args) if (!response.ok) { // *** .ok is simpler than .status == 200 throw new Error(errmsg); } return response.json(); } async function deezer() { const reqGenero = new Request('); const generos = await fetchJson('Erro ao pegar gêneros', reqGenero); var generoId = generos.data[Math.floor(Math.random() * 10 + 1)].id; //console.log('\ngenero... ' + generoId); const artistas = await fetchJson('Erro ao pegar artistas', ' + generoId + '/artists'); /* 1 música de 4 artistas */ // *** Use Promise.all to wait for the four responses return Promise.all(artistas.data.slice(0, 4).map( entry => fetchJson('Erro ao pegar música', ' + entry.id + '/top') )); } 
2

You can replace the statement

// CAN I SEND THIS REQUEST 4 TIMES? return fetch(' + ids + '/top'); 

with

const fetchResults = []; artistasIds.forEach(function(ids){ fetchResults.push(fetch(' + ids + '/top')); }); return Promise.all(fetchResults); 

in then condition you'll get an array of values with top music from each artist. I haven't checked with the given API, but ideally it should work.

You can create 4 requests and wait for all of them to complete, using Promise#all.

.then(artistas => { /* 1 música de 4 artistas */ const artistasPromises = artistas.data.map(artista => fetch("" + artista.id + "/top").catch( err => ({ error: err }) ) ); return Promise.all(artistasPromises); }).then(musicList => { console.log(musicList); }); 

Notice the catch(). This makes sure that even if a fetch fails, the other fetch results are not ignored. This is because of the way Promise#all works. So, you need to iterate over musicList and check if there is any object of the shape { error: /* error object */ } and ignore that while processing the list.

Yes you can make 5 requests (not 4 its 0-4) and wait for each to complete. Use Array.prototype.map to create an array of request promises.(prefer over for- forEach and array.push)

and Promise.all to wait for all the promises to get complete, which will return the array of resolved responses, if no failures.

.then(artistas => { /* 1 música de 4 artistas */ var artistasIds = []; let ids = artistas.data.map(artist => artist.id).slice(0, 4); requests = ids.map(id => fetch(`)); return Promise.all(requests); } }) 

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

You Might Also Like