In order to output a CSV file, I want to build an array of data from a MongoDB collection.
I use forEach into a promise and I want to resolve when all the records have been read.
However my code below does not work. The promise is never resolved. It seems there is a bug with the if/else condition. Is there another way to know when the forEach loop is done?
exports.eachRecord = function () {
return new Promise(function (resolve, reject) {
var data = []
mongoClient.connect(process.env.MONGO, function (err, db) {
// Handled connection error
if (err) { return console.log(err) }
db.collection('log').find().forEach(function (doc) {
if (doc !== null) {
console.log(doc.ug)
data.push(doc.ug)
} else {
db.close()
console.log('done!')
resolve(data)
}
})
})
})
}
Any idea? Thank you very much.
The mongodb, since v3.0, support the cursor.forEach(iterator, endCallback)
We must distinguish between:
toArraySo to archive your needsyou need only to add a callback:
exports.eachRecord = function () {
return new Promise(function (resolve, reject) {
const data = []
mongoClient.connect(process.env.MONGO, function (err, db) {
if (err) { return reject(err) }
db.collection('log').find().forEach(
doc => { data.push(doc.ug) },
err => {
if (err) { return reject(err) }
resolve(data)
})
})
})
}
forEach is synchronous.
The problem is with your mongodb call, which is not asynchronous. You can make it asynchronous by adding it a callback.
db.collection('log').find({}, (err, data) => {
if (error) ...
data.forEach((doc) => { ... });
// Whatever you want to do after forEach.
});
You can use this code :
function getData() {
return new Promise((resolve, reject) => {
var data = db.collection('credit_history').find({
'history.dt': '2019-04-25'
}).toArray((err, res) => {
if (err) reject(err);
resolve(res);
});
}).catch((ex)=>{
console.log(ex);
});
}
var array_data =[] ;
var data = await getData().then((data)=>{
data.forEach((el)=>{
console.log(el.p);
array_data.push(el.p) ;
})
});