basically I have a big array with object values like this:
[{
- Champion Name
- [Another Array with Skins information]
}]
so what I want to do is run a map function inside the second array to get a value for everyone of these skins so what I did was.
const got = require('got');
const cheerio = require('cheerio');
const fs = require('fs').promises;
const getSkinData = async champSkins => {
const data = JSON.parse(champSkins);
const handleMap = skin => {
return new Promise(async (resolve, reject) => {
try {
const name = skin.split(' ').join('_');
const { body } = await got(`https://lol.gamepedia.com/${name}`);
const $ = cheerio.load(body);
const skinLink = $('.InfoboxSkin img').attr('src') || '';
const skinInfo = {
skinName: skin,
skinLink
};
resolve(skinInfo);
} catch (err) {
console.error(err.message);
}
});
};
Promise.all(
data.map(async ({ skins }) => {
return Promise.all(
skins.map(skin => {
return handleMap(skin);
})
);
})
).then(data => console.log(data));
};
module.exports = getSkinData;
but it didn't actually work, I couldn't access the data and the console.log inside the promise at the end didn't even run.
any idea how to do it or is there a better way to do it?
EDIT #1
basically 'skins' for every champ is an array of strings like:
[ 'Aatrox',
'Justicar Aatrox',
'Mecha Aatrox',
'Sea Hunter Aatrox'
'Blood Moon Aatrox'
'Blood Moon Aatrox
'Victorious Aatrox' ]
[ 'Ahri',
'Dynasty Ahri',
'Midnight Ahri',
'Foxfire Ahri',
'Popstar Ahri',
'Challenger Ahri',
'Academy Ahri',
'Arcade Ahri',
'Star Guardian Ahri
'K/DA Ahri',
'K/DA Ahri Prestige
'Elderwood Ahri' ]
and skin is just every value of the array
and the value that comes back from the scraping is just a link for each skin
const getSkinData = async champSkins => {
const data = JSON.parse(champSkins);
// async that returns promise is a double promise, you only need async
const handleMap = async skin => {
try {
const name = skin.split(" ").join("_");
const { body } = await got(`https://lol.gamepedia.com/${name}`);
const $ = cheerio.load(body);
const skinLink = $(".InfoboxSkin img").attr("src") || "";
const skinInfo = {
skinName: skin,
skinLink
};
// changed resolve to return
return skinInfo;
} catch (err) {
console.error(err.message);
}
};
return await Promise.all(data.map(({ skins }) => Promise.all(skins.map(skin => handleMap(skin)))));
};
Async functions return a promise that resolves with their return value, so returning a promise from an async function is redundant and ends up causing a nested promise. Also, you don't have to use .then
in async functions because you can just await
the promise. Read more about Promises and async/await.