1

I'm trying to put element in an array that have been define externaly a method.

let result = JSON.parse(body);
let objects = [];
result.results.forEach(element => {
    getObjectDetail(element.place_id).then((detail) => {
        console.log(detail);
        let object = {
            place_id: element.place_id,
            name: element.name,
            rating: element.rating,
            address: detail.result.formatted_address,
            photo:
                   googleApiHost +
                   googlePlacePrefix +
                   googlePlacesPlaceImageUri +
                   '?key=' +
                   googleApiKey +
                   '&maxwidth=400&photoreference=' +
                   element.photos[0].photo_reference,
                   website: detail.result.website
         }
         console.log(object);
         objects.push(object);
     });
});
console.log(objects);

console.log(object) give me the good result with all fields setted. But console.log(objects) return an empty array

2 Answers 2

1

This is the whole idea of promise- it operates asynchronously and executes the .then clause when it is resolved. But meanwhile, the main code flow continues to execute.

Effectively this means that in your case, the flow goes like this: enter forEach loop > initialize a seperate promise for each element > log(objects) > execute the .then clause for every promise resolved.

So the logging executes before any promise is resolved and any item is pushed to objects. Your best bet here is to use Promise.all, which operates on array of promises and returns a resolved promise when all of the promises are resolved, or a rejected promise whenever one promise is rejected.

let result = JSON.parse(body);
let objects = [];
let objectsPromises = [];
result.results.forEach( (element, index) => {
    objectsPromises[index] = getObjectDetail(element.place_id);
});
Promise.all(objectsPromises).then( (values) => {
   // The "values" is an array containing all the values of the resolved promises.
   // You can now iterate over it and perform the code in your `.then` clause for each 
   //promise, and then manipulate the objects array, as this iteration is synchronous 
   // (operates on actual values and not promises)
}
console.log(objects); // NOTE: THIS WILL STILL LOG EMPTY ARRAY!
Sign up to request clarification or add additional context in comments.

Comments

0

You can use for of loop better than for each, because the forEach loop contains a callback and try using async await it makes the code more readable.

const func = async ()=> { 
    let result = JSON.parse(body);
    let objects = [];
    for (var element of result.results) {
    var detail = await getObjectDetail(element.place_id);
        console.log(detail);
        let object = {
            place_id: element.place_id,
            name: element.name,
            rating: element.rating,
            address: detail.result.formatted_address,
            photo: googleApiHost +
                    googlePlacePrefix +
                    googlePlacesPlaceImageUri +
                    '?key=' +
                    googleApiKey +
                    '&maxwidth=400&photoreference=' +
                    element.photos[0].photo_reference,
                    website: detail.result.website
            }
        console.log(object);
        objects.push(object);
    }
}

console.log(objects);

1 Comment

I haven't tried this cause the first answer works, but it seems to be a good solution. Thanks

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.