I'm using an api that has data on two endpoints:
I actually need to get all of the properties and I'm planning to build a master object to drive my UI.
Current functions:
Behaviour:
Problem : - both my functions resolve, but my final object contains Promise.resolve objects. The objects have the correct values.
Code
const getNews = async options => {
try {
const { data } = await axios(options);
const parsedEnDataWithMeta = parsedEnData.map(article => {
const mergedArticleWithMeta = {
...article,
...getMetaPerArticle(article.id)
};
return mergedArticleWithMeta;
});
} catch (getNewsError) {
dispatch(receiveNewsError(getNewsError));
}
};
const getMetaPerArticle = async articleID => {
const axiosOptions = {
method: "GET",
url: `url`,
};
try {
const response = await axios(axiosOptions);
return response.data;
} catch (err) {
console.error(err);
dispatch(receiveNewsError(err));
}
};
Output
(6) [{…}, {…}, {…}, {…}, {…}, {…}]
0: {
abstract: "",
...
metadata: Promise {<resolved>: {...}}
}
getMetaPerArticle returns a promise, so you'll need to wait for those promises to resolve before you try to map to parsedEnDataWithMeta. Something like this:
const getNews = async options => {
try {
const { data } = await axios(options);
const metadataPromises = data.map(article => getMetaPerArticle(article.id));
const metadata = await Promise.all(metadataPromises);
const parsedEnDataWithMeta = data.map((article, i) => ({
...article,
...metadata[i]
});
} catch (getNewsError) {
dispatch(receiveNewsError(getNewsError));
}
};
Your Problem is that getMetaPerArticle
returns a Promise so you need to add an await
in fornt of it, and mark the arrow function as async
.
const parsedEnDataWithMeta = parsedEnData.map(async article => {
const mergedArticleWithMeta = {
...article,
...await getMetaPerArticle(article.id)
};
return mergedArticleWithMeta;
});
After that parsedEnDataWithMeta
will hold a list of Promises, so you would need to wait untill all of them are resolved using Promise.all
:
const parsedEnDataWithMeta = await Promise.all(parsedEnData.map(async article => {
const mergedArticleWithMeta = {
...article,
...await getMetaPerArticle(article.id)
};
return mergedArticleWithMeta;
}));
If you need to use that more often then you could define you a map function that will handle promises:
function promiseMap( array, callback ) {
return Promise.all(array.map(callback))
}
const parsedEnDataWithMeta = await promiseMap(parsedEnData, async article => {
const mergedArticleWithMeta = {
...article,
...await getMetaPerArticle(article.id)
};
return mergedArticleWithMeta;
});
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.