Reputation: 1
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
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).
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 */
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 */
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