0

Here I am using this function to check the DB if the place already exists in the database, if not I plan to add it (not yet implemented).

function pairPlaces(parsed, callback) {

    for (var placeKey in parsed.results) {
        var place = parsed.results[placeKey];
        var placeid = place.place_id;
        var name = place.name;
        var lat = place.geometry.location.lat;
        var lng = place.geometry.location.lng;
        var vicinity = place.vicinity;

        console.log(placeKey + "::" + name + "-" + placeid);

        client.execute("select * from places where placeid='"+placeid+"'", function(err, result) {
            if(!err) {
                if(result.rows.length > 0) {
                    console.log('Found...');
                } else {
                    console.log('Added: ' + name);
                }
            }else {
                console.log('DB ERR: %s', err);
            }
        });
    }
    callback(parsed);
}

However, after it checks the database and sees that none of the places are added the console logs the same place name as the last one in the loop as opposed to the corresponding place that would have been queried. What am I doing wrong?

Console output from the above function:

0::Harry's Chocolate Shop-ChIJNx4C967iEogRjyKJNWYeSjs
1::Brother's Bar & Grill-ChIJV5TTw67iEogRZF2mm1f6K-0
2::Jake's Roadhouse-ChIJ6SGX2a7iEogRB_d9evKamGQ
3::Qdoba Mexican Grill-ChIJofbRu67iEogRpPnhaYGiwl0
4::Juilliard-ChIJSUzXka7iEogRlPiKfmP5fc4
Added: Juilliard
Added: Juilliard
Added: Juilliard
Added: Juilliard
Added: Juilliard
user3916570
  • 780
  • 1
  • 9
  • 23
  • `.execute()` is asynchronous and doesn't block, so the loop runs to completion before the first `function(err, result)` is invoked. Also, `var`s are only declared once per `function`, they're reused for the entire loop and can only keep one of the values set to them. Either use [`let`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let) instead of `var`, which will make them block-scoped, or redeclare the variables with another function/closure. [JavaScript closure inside loops – simple practical example](http://stackoverflow.com/questions/750486/) – Jonathan Lonowski Dec 26 '15 at 16:04
  • Also: [Javascript infamous Loop issue?](http://stackoverflow.com/questions/1451009/javascript-infamous-loop-issue) * [Please explain the use of JavaScript closures in loops](http://stackoverflow.com/questions/3572480/please-explain-the-use-of-javascript-closures-in-loops) – Jonathan Lonowski Dec 26 '15 at 16:08
  • How do I make sure that the loop executes in order and then once all of the client.executes are done it can then perform the callback (see question edit), because if I am understanding this right it will call the callback once it starts all the client.executes as opposed to once they have all completed. – user3916570 Dec 26 '15 at 16:18
  • Standard loops can't be used to control the order when using asynchronous functions or to be aware when all have completed. If each iteration created a `Promise` instead, you could use [`Promise.all()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all). Or, to stick with callback arguments, "[Asynchronous for cycle in JavaScript](http://stackoverflow.com/questions/4288759/asynchronous-for-cycle-in-javascript)" offers one option. The [`async` module](https://www.npmjs.com/package/async) is also a common recommendation. – Jonathan Lonowski Dec 26 '15 at 16:24

0 Answers0