aclark13861
aclark13861

Reputation: 1

Pushing mongoDB results to an array, but the array remains empty

This is my first question on stack overflow, so bear with me.

So I have a controller function that is rendering my google maps api, and I am trying to loop through the results from mongoDB and push them to an array so that I can pass it to a script tag on the ejs. I am able to console.log(myArr) within the for loop and get results, but not outside of it (just above the res.render). I am assuming my that my problem is my result within res.render is receiving an empty array.

Please help me I have been stuck on this problem for days now. Thank you, Andrew

function showMap(req, res) {
  let myArr = [];
  db.collection("poppies").find().toArray(function (err, result) {
    for (let i = 0; i < result.length; i++) {
        myArr.push(result[i].Address);
    };
  });
  res.render('map', {
    result: JSON.stringify(myArr)
  })
};

Upvotes: 0

Views: 279

Answers (1)

Ezra Siton
Ezra Siton

Reputation: 7781

Asynchronous Javascript allows you to execute operations without waiting for the processing thread to become free.

Imagine the data loads from your DB only after 3 seconds - you should "wait" to get the value from your DB before running the next line code. In your case you use myArr "outside" without await -Or- promises -Or- callbacks) - So the value is an empty array.

IMPORTANT: The idea of Asynchronous Javascript is a topic for a course (No way to cover this issue by StackOverflow Answer).

Not working

length is: undefined

function helloWorld() {
  let items = db.collection("newspapers").find({}).toArray();
  return (items);
};

const result = helloWorld();
console.log("length is: " + result.length); /* length is: undefined */

Working

await for the value from helloWorld() function.

function helloWorld() {
  let items = db.collection("newspapers").find({}).toArray();
  return (items);
};

const result = await helloWorld();
console.log("length is: " + result.length); /* length is: 337 */

In practice

Promise chaining for example:

For this database:

[
  {
    "Newspaper": "The New York Times"
  },
  {
    "Newspaper": "Washington Post"
  }
]

const dbName = 'my_database';
await client.connect();
const db = client.db(dbName);

myArr = [];
db.collection("newspapers").find({}).toArray()
  .then(
    res => {
      for (let i = 0; i < res.length; i++) {
        myArr.push(res[i].Newspaper);
      };
      console.log(`The length is ${res.length} documents`) /* The length is 2 documents */
      console.log(myArr); /* [ 'The New York Times', 'Washington Post' ] */
     },
    err => console.error(`Something went wrong: ${err}`),
);

try/catch Async/await example (Readable code pattern):

const helloWorld = (async () => {
  try {
    let items = await db.collection("newspapers").find({}).limit(2).toArray();
    return (items);
  } catch (e) {
    console.error(
      `Unable to establish a collection: ${e}`,
    )
  }
})

const result = await helloWorld();
console.log("length is: " + result.length); /* length is: 2 */

More examples here: https://docs.mongodb.com/drivers/node/fundamentals/promises

Upvotes: 1

Related Questions