Here is my code
let url;
let planetCount;
let planetData = [];
//turn through the pages
for (let p = 1; p < 7; p ) {
url = `https://swapi.boom.dev/api/planets?page=${p}`;
//fetch data
for (let j = 0; j < 1; j ) {
fetch(url).then(res => res.json())
.then(data => {
//push data to array
for (let i = 0; i < data.results.length; i ) {
planetData.push(data.results[i]);
}
})
console.log(planetData)
}
}
And here is the output: https://i.stack.imgur.com/Hivwr.png
Problem: How do I make it so it all goes into one array, instead of 6?
CodePudding user response:
You do have only one array. You just get an output six times because you run console.log()
within a loop.
I expanded your code with the proper way to handle several async calls and wait until they are all finished:
let url;
let planetCount;
let planetData = []
let promises = [];
//turn through the pages
for (let p = 1; p < 7; p ) {
url = `https://swapi.boom.dev/api/planets?page=${p}`;
//fetch data
for (let j = 0; j < 1; j ) {
promises.push(fetch(url).then(res => res.json())
.then(data => {
//push data to array
for (let i = 0; i < data.results.length; i ) {
planetData = planetData.concat(data.results[i]);
}
}));
}
}
Promise.all(promises)
.then(() => {
console.log(planetData.length, '=>', planetData);
})
CodePudding user response:
You can use async/await
and Promise.all()
to return an array of the pages returned. Once we have this, we can use Array.flat()
to create a contiguous array of planet data:
async function getPlanets() {
const urls = Array.from( { length: 7 }, (v,i) => `https://swapi.boom.dev/api/planets?page=${i 1}` );
const promises = urls.map(url => fetch(url).then(res => res.json()).then(data => data.results));
const planetData = (await Promise.all(promises)).flat();
console.log(`Results for ${planetData.length} planets downloaded...`);
console.log('Results:', planetData);
}
getPlanets()
CodePudding user response:
Does this answer your question? How can I fetch an array of URLs with Promise.all?
Promise all should be the right tool for you to use so that you wait until all promises are resolved before handling responses
CodePudding user response:
The issue is related to how async code works.
the fetch()
function will eventually return a result, but that result is not available at the time you are trying to log it.
You must wait for the result to be retrieved. Use Aysnc/Await
to accomplish that:
async function turnThroughThePges() {
let url;
let planetCount;
let planetData = [];
//turn through the pages
for (let p = 1; p < 7; p ) {
url = `https://swapi.boom.dev/api/planets?page=${p}`;
//fetch data
for (let j = 0; j < 1; j ) {
await fetch(url).then(res => res.json())
.then(data => {
for (let i = 0; i < data.results.length; i ) {
planetData.push(data.results[i]);
}
})
}
}
return planetData;
}
turnThroughThePges().then(console.log);
CodePudding user response:
async function requests(){
let url;
let planetCount;
let planetData = [];
//turn through the pages
for (let p = 1; p < 7; p ) {
url = `https://swapi.boom.dev/api/planets?page=${p}`;
//fetch data
await fetch(url).then(res => res.json())
.then(data => {
for (let i = 0; i < data.results.length; i ) {
planetData.push(data.results[i]);
}
})
}
return planetData;
}
requests().then(console.log)
// useless loop for (let j = 0; j < 1; j )
CodePudding user response:
let url;
let promises = [];
//turn through the pages
for (let p = 1; p < 7; p ) {
url = `https://swapi.boom.dev/api/planets?page=${p}`;
//fetch data
promises.push(
fetch(url)
.then((res) => res.json())
.then((data) => data.results)
);
}
function handleRejection(p) {
return p.catch((err) => ({ error: err }));
}
async function requests() {
return await Promise.all(promises.map(handleRejection));
}
requests().then((planetData) => console.log(planetData.flat()));