Below is my code
var mongodb = require('mongodb');
var MongodbClient = mongodb.MongoClient;
MongodbClient.connect('mongodb://localhost/test', function(err, db) {
db.collection('contact', function(err, collection) {
collection.find({}, function(err, rows) {
for(var index in rows)
console.log(rows[index]);
});
});
var contact = db.collection('contact');
contact.insert({
name:'Fred',
tel:'123456789',
address: 'Mars',
}, function(err, docs) {
if(err){
console.log("failed")
return;
}
else{
console.log('Success');
}
});
contact.find({}, function(err, docs) {
if(err) {
console.log("Can not find any!");
return;
}
for(var index in docs) {
console.log(docs.length);
var doc = docs[index];
console.log(doc.name);
}
});
});
I can find the data using mongodb shell but in node, it shows
TypeError: Cannot read property 'name' of null
on console.log(doc.name).
and also shows "undefined" when try to console.log(docs.length);
Did I do something wrong?
You are not using correctly the mongodb node API:
You should have:
contact.find({}).toArray(function(err,results) {
if (err) {
console.debug(err);
return;
}
console.debug(JSON.stringify(results));
});
More on docs.
You can try JSON.stringify(object) and then JSON.parse(object) and then try to access the property.
let xxxxxxxx = async (req, res) => {
let resultSet = [];
let object;
let perDayData = await yyyyyyyyyyy.find({});
perDayData = JSON.stringify(perDayData);
perDayData = JSON.parse(perDayData);
console.log(perDayData[0].field);
}
Related
I have set up node and mongodb and have imported some yelp data into mongo. When I query using the mongo shell, I can see there are documents and everything is fine. However I'm unable to pass them along by adding them to an array and returning that array. When I hit up localhost:3000/api/reviews, I get a blank page. My console does log everything though so the node driver for mongo is working in getting the documents. Any ideas? I feel like it has something to do with the asynchronous nature of node.
var express = require('express');
var router = express.Router();
var MongoClient = require('mongodb').MongoClient;
var assert = require('assert');
var url = 'mongodb://localhost:27017/YelpDB';
var getReviews = function(db, callback) {
var cursor = db.collection('reviews').find( );
//JSONArray jsonarray = new JSONArray();
var data = [];
cursor.each(function(err, doc) {
assert.equal(err, null);
if (doc != null) {
var jsonDoc = JSON.stringify(doc);
console.log(typeof jsonDoc);
data.push(jsonDoc);
} else {
callback();
}
});
return data;
};
router.get('/reviews/', function(req, res, next) {
//res.send('respond with a resource');
MongoClient.connect(url, function(err, db) {
assert.equal(null, err);
var data = getReviews(db, function() {
db.close();
});
res.json({"reviews": data});
});
});
Please try this one, you should return the data at the end of cursor.each in the callback function.
var getReviews = function(db, callback) {
var cursor = db.collection('reviews').find( );
var data = [];
cursor.each(function(err, doc) {
if (err)
callback(err);
if (doc) {
var jsonDoc = JSON.stringify(doc);
console.log(typeof jsonDoc);
data.push(jsonDoc);
} else {
// at the end of cursor, return the data through callback
callback(null, data);
}
});
};
router.get('/reviews/', function(req, res, next) {
//res.send('respond with a resource');
MongoClient.connect(url, function(err, db) {
assert.equal(null, err);
getReviews(db, function(err, data) {
if (err)
throw err;
// send the data in callback function
res.json({"reviews": data});
db.close();
});
});
});
It turns a funny error in Node.js mongodb, if I put the form below:
locals.collection.find(filter, req.query);
returns me the following error:
MongoError: query selector must be an object
Now if I manually put the query works.
I'm having this problem a long time, and I've tried several ways.
locals.collection.find({slug:'somak'}, req.query);
I am using the following function:
exports.findAll = function(req, res, next) {
var locals = {},
section = req.params.section,
query = req.query,
filter = {};
if(query.filter) {
filter = query.filter.replace(/"(\w+)"\s*:/g, '$1:');
filter = filter.replace(/["]/g, "'");
}
console.log(filter);
delete query.filter;
async.series([
function(callback) {
MongoClient.connect(url, function(err, db) {
if (err) return callback(err);
locals.collection = db.collection(section);
callback();
});
},
function(callback) {
locals.collection.count(filter, function (err, result){
if (err) return callback(err);
locals.count = result;
callback();
});
},
function(callback) {
var cursor = locals.collection.find({slug:'somak'}, req.query);
if(req.query.page) {
cursor = cursor.skip(Math.abs(req.query.limit) * --req.query.page);
}
cursor.toArray(function(err, docs) {
if (err) return callback(err);
locals.docs = docs;
callback();
});
}
],
function(err) { //This function gets called after the three tasks have called their "task callbacks"
if (err) return next(err);
// Here locals will be populated with 'count' and 'docs'
res.json({
count: locals.count,
data: locals.docs
});
});
Just use JSON.parse:
exports.findAll = function(req, res, next) {
var locals = {},
section = req.params.section,
query = req.query,
filter = {};
if(query.filter) {
filter = JSON.parse(query.filter);
}
delete query.filter;
...
I am writing the filter using mongodb native driver, but it's driving me this error when you run the query.
In the case of this driver, it has no exec?
What is another way to perform this query?
exports.findAll = function(req, res) {
MongoClient.connect(url, function(err, db) {
var section = req.params.section;
var collection = db.collection(section);
var filter = req.query.filter ? {nameToLower: new RegExp('^' + req.query.filter.toLowerCase())} : {};
var query = collection.find(filter);
var count = 0;
collection.count(filter, function (error, result) {
count = result;
});
if(req.query.order) {
query.sort(req.query.order);
}
if(req.query.limit) {
query.limit(req.query.limit);
if(req.query.page) {
query.skip(req.query.limit * --req.query.page);
}
}
query.exec(function (error, results) {
res.json({
count: count,
data: results
});
});
});
};
Error:
TypeError: undefined is not a function
Better to use the async library in this case as it simplifies the code. In the case where you need to run multiple tasks that depend on each other and when they all finish do something else, use the
async.series() module. The following demonstrates how you can go about this in your case:
exports.findAll = function(req, res) {
var locals = {},
section = req.params.section,
filter = !!req.query.filter ? {nameToLower: new RegExp('^' + req.query.filter.toLowerCase())} : {};
async.series([
// Connect to DB
function(callback) {
MongoClient.connect(url, function(err, db) {
if (err) return callback(err);
locals.collection = db.collection(section); //Set the collection here, so the next task can access it
callback();
});
},
// Get count
function(callback) {
locals.collection.count(filter, function (err, result){
if (err) return callback(err);
locals.count = result; //Set the count here
callback();
});
},
// Query collection
function(callback) {
var cursor = locals.collection.find(filter);
if(req.query.order) {
cursor = cursor.sort(req.query.order);
}
if(req.query.limit) {
cursor = cursor.limit(req.query.limit);
if(req.query.page) {
cursor = cursor.skip(req.query.limit * --req.query.page);
}
}
cursor.toArray(function(err, docs) {
if (err) return callback(err);
locals.docs = docs;
callback();
});
}
], function(err) { //This function gets called after the three tasks have called their "task callbacks"
if (err) return next(err);
// Here locals will be populated with 'count' and 'docs'
res.json({
count: locals.count,
data: locals.docs
});
res.render('user-profile', locals);
});
};
Hi I have this code but when finish the result is not the espected because didn't run in the sequence that I wish
here is the code:
var user_data = {};
models.games.find({$or: [{w_id: req.user._id}, {b_id: req.user._id}, {owner: req.user._id}]}, function (err, games) {
var req_games = [];
if (!err) {
for (var i in games) {
req_games.push(games[i]);
models.users.findOne({_id: games[i].w_id}, function (err, user) {
req_games[i].w_id = user.user;
console.log(req_games[i].w_id) //< -- 3
});
console.log('a ' + req_games[i].w_id) //<-- 2
}
user_data.games = req_games; // <-- 1
}
});
at the end of the task req_games didnt have any update because it's running in the sequence that I put in the comments in the code
This may help you using Q(promises)
obj.find = function(model, condition) { //make your find to return promise
var deferred = q.defer();
model.find(condition, function(err, results) {
if (err) {
logger.log(err);
deferred.reject(err);
} else {
deferred.resolve(results);
}
});
return deferred.promise;
}
ArraysOfId.forEach(function (id) {
var tempProm = mongoUtilsMethodObj.find(schemaObj.Asset, id).then(function (assetObj) {
---- your code
return q.resolve();
});
promArr.push(tempProm);//push all promise to array
});
q.all(promArr).then(function () {
// this will be called when all promise in array will we resolved
})
Here is a version using the async library to map your game values.
var async = require('async');
var user_data = {};
models.games.find({$or: [{w_id: req.user._id}, {b_id: req.user._id}, {owner: req.user._id}]}, function (err, games) {
if(err) {
// or whatever your error response happens to be
return res.render('user.swig', {error: err});
}
async.map(games, function(game, nextGame) {
models.users.findOne({_id: game.w_id}, function (err, user) {
game.w_id = user.user;
nextGame(err, game);
});
}, function(err, req_games) {
user_data.games = req_games;
res.render('user.swig', {user: user_data});
});
});
I am working with node.js using express and mongoDb.
I am trying to retrieve data from database "local" and collection "borrower" and pushing it into an empty array collectionOne. It is rendering this array on the view page.
I want to use _id pushed in an array b_ids from this output to make a call to company_details collection under same router .
The issue I am facing here is I am not getting any value in array b_ids when trying to access it under call to company_details collection.
The code is as below:
var collectionOne = [];
var collectionTwo = [];
var b_ids = [];
router.get('/fetch',function(req, res, next){
MongoClient.connect('mongodb://localhost:27017/local', function(err, db){
var collection = db.collection('borrower');
db.collection("borrower", function(err, collection) {
collection.find().toArray(function(err, result) {
if (err) {
throw err;
} else {
//console.log(result[0].first_name);
for (i=0; i<result.length; i++) {
collectionOne[i] = result[i];
b_ids[i] = result[i]._id;
}
}
});
db.collection("company_details", function(err, collection){
console.log(b_ids);
collection.find({borrower_id : {$in :b_ids}}).toArray(function(err, result){
if (err) {
throw err;
} else {
for (i=0; i<result.length; i++) {
collectionTwo[i] = result[i];
}
}
});
});
res.render('index',{data : collectionOne , data1 : collectionTwo});
});
});
});
Please suggest me how can I access the b_ids array here. Thanks in advance :)
The callback from toArray is asynchronous, i.e. will happen after your console.log line executes, therefore you need to re-arrange as follows:
var collectionOne = [];
router.get('/fetch',function(req, res, next){
MongoClient.connect('mongodb://localhost:27017/local', function(err, db){
var collection = db.collection('borrower');
db.collection("borrower", function(err, collection) {
collection.find().toArray(function(err, result) {
if (err) {
throw err;
} else {
for (i=0; i<result.length; i++) {
collectionOne[i] = result[i];
b_ids[i] = result[i]._id;
}
db.collection("company_details", function(err, collection){
console.log(b_ids);
collection.find({borrower_id : {$in :b_ids}}).toArray(function(err, result){
if (err) {
throw err;
} else {
for (i=0; i<result.length; i++) {
collectionTwo[i] = result[i];
}
res.render('index',{data : collectionOne , data1 : collectionTwo});
}
});
});
}
});
});
});
This ensures that the callback completes before you try and log / render it.
It is simple create a function with a callback function inside it as an argument
function returnBids(collection, callback){
collection.find().toArray(function(err, result) {
if (err)
throw err;
else
callback(result)
})
}
and you can access your result outside by calling the function returnbids() .i.e
returnBids(collection,function(b_ids){
console.log(b_ids)
})