Hey I have written this code in node js
async function getUdemydata(){
try{
var finalData = []
const res = await axios.get(baseUrl)
const $ = cheerio.load(res.data);
$('div[class="content"]').each(async (i,el) =>{
const courseTitle = $(el).find("a").text()
const aa = $(el).html()
const courseUrl = await getCoupenCode($(el).find("a").attr("href"))
const courseDescription = $(el).find(".description").text().trim()
const courseImage = await formateImageUrl($(el).find(".image").html())
var dataObj = {
"title": courseTitle,
"description": courseDescription,
"image": courseImage,
"link": courseUrl
}
finalData.push(dataObj);
console.log('appended');
})
return (finalData);
} catch(error){
console.error(error);
}
}
(async()=>{
var rs = await getUdemydata();
console.log(rs);
})()
When I call the getUdemydata() function only the empty array is printed after that appended which is inside the function is being printed what should I change in the code so that the function will return the final array
>Solution :
The definition of .each is as follows:
each<T>(fn: (i: number, el: T) => boolean | void): Cheerio<T>
It is not Promise-aware, so does not await the async function you supply as its parameter.
Remember that an async function is just a normal function that returns a Promise, so you could map these function calls, ending up with an array of Promise, then wait for them all.
// var finalArray = [] // <-- NO
const promises = $('div[class="content"]')
.toArray()
.map(async (el,i) => {
// same body as `each` in your code
// except, don't push into `finalArray`
// just return your value
// finalData.push(dataObj); // <-- NO
return dataObj;
});
const finalArray = await Promise.all(promises);
or if the parallelism of running all those promises at once is too much, then the documentation suggests that a Cheerio is Iterable, so just loop over $('div[class="content"]') with a normal
for(const el of $('div[class="content"]')) { //...