The api response
consisting of properties such as films
and vehicles
array of urls and by fetching those
, I’m trying to get the resultant objects
and trying to update it back inside those mentioned properties.
After returning the promises using Promise.all
, I’m trying to set the films
and vehicles
with the results, but I’m unable to get the desired output. Here’s my Working Code Link
Any help regarding the problem would be appreciated.
I’m getting the below issue after setting films
and vehicles
in the response objects after waiting for promises to get the results:
Here in this case, I’m getting the films
first but not with the desired output
where the films needs to the array of objects
, but instead getting the promise status
.
Next, I’m getting the films
result as pending
and vehicles
promise fulfilled
result instead of the resultant array of objects in the mentioned object properties.
How to reolve this issue? My one only desired output is to get the films and vehicles array of objects inside the response object which I have kept in the newState
.
Please find my code below:
import { useEffect, useState } from "react";
const url = `https://swapi.dev/api/people/`;
export function ToDo() {
const [results, setResults] = useState([]);
useEffect(() => {
apiCallHandler(url);
}, []);
async function asyncAllPromises(arr) {
const promises = await arr.map(async (item) => {
const response = await fetch(item, { cache: "no-cache" });
const json = await response.json();
return json;
});
const response = await Promise.all(promises);
return response;
}
const apiCallHandler = async () => {
try {
const response = await fetch(url);
let data = await response.json();
let newState = data.results.map((result) => {
result.films = asyncAllPromises(result.films).then((data) => data);
result.vehicles = asyncAllPromises(result.vehicles).then(
(data) => data
);
return result;
});
setResults(newState);
} catch (error) {
console.error("Unable to find data", error);
}
};
console.log("results", results);
const table =
results && results.length ? (
<table>
<thead>
<tr>
<td>Name</td>
<td>Mass</td>
</tr>
</thead>
<tbody>
{results.map((result, index) => {
return (
<tr key={index}>
<td>{result.name}</td>
<td>{result.mass}</td>
</tr>
);
})}
</tbody>
</table>
) : (
"Loading.."
);
return <>{table}</>;
}
2
Answers
You forgot to call
await
in lines 27 and 28, soresult.films
is kept as aPromise
. In addition, the.then(data=>data)
is redundant.Therefore, the definition of newState should be changed to:
The
Promise.all()
is used to convert thePromise
s returned by theasync
mapper function back into onePromise
which is thenawait
ed.Hope this helps!
Your issue is because of how
newState
is calculatedSince
asyncAllPromises
is returning aPromise
, you need to wait for it. Second,map
will be returning aPromise
. You so need to wait for it as well.You can fix this issue by: