I'm using an API with some limited functionality, and I'm trying to combine several calls to multiple routes to serve the user specific information based on a single keyword search. This creates a lot of separate requests within for loops, which are themselves inside the callbacks of other request results, etc. In the end I'm not being able to wait for all nested requests to be done until I resolve the original Promise and my template engine renders the page and responds to the users get request. Therefore the templating engine is rendering a page with a still empty array of results.
let discoveredMovies = [];
let personSearchCast = new Promise ((resolve) => {
request(UserSearchParamsURL1, {json:true}, (err, res, body) =>{
if (err) {
console.log(err);
resolve();
}
else if(!body.results.length || !body) {
resolve();
}
else {
for (const person of body) {
request(URL2, {json: true}, (err, res2, body2) => {
for (const movie of body2) {
request(URL3, {json:true}, (err, res3, body3) => {
movie[CertainParam] = false;
if (Certain Conditions) {
discoveredMovies.push(movie);
}
if (Other Conditions) {
discoveredMovies.push(movie);
}
if(More Conditions) {
movie[CertainParam] = true;
Object.assign(movie, {body3info: body3});
}
resolve();
});
};
});
};
}
});
});
personSearchCast.then(() => {
res.render("partials/foundpeoplemovies.ejs", {movies: discoveredMovies});
});
As it stands I know that all the Request calls do happen since I can log them out, but the template renders before they can finish. I've tried creating several async await functions and trying to connect them but I just can't wrap my head around it. I also tried using counters to condition the resolve() until all the loops within loops were finished, but that didn't get me too far either.
I know the code is messy, but any ideas how to cleanly do what I'm trying to do? Otherwise I'll have to mess with the user interface and add a series of intermittent steps for the user instead of serving the user all the info in one quick search.