How to query in MongoDB in function and res.render to ejs - node.js

I want to query last 10 elements in Mongodb and return elements in this query for render to index.ejs I try a lot of way for this for example (callback,asyc function) but I can't fix this problem
function getlastelements(ID){
var MongoC = mongodb.MongoClient;
var url = 'mongodb://localhost:27017/Weatherdb';
MongoC.connect(url, function(err,db){
var collection = db.collection('datas');
collection.find({"ID" : String(ID)}).sort({_id:-1}).limit(10),(function(err,cursor){
var xyz = cursor.toArray();
return(xyz.length);
})
});
}
console.log(getlastelements(1));

Your function can return a promise on which you can call the .then() method to get the value (also, remember to close the db at the end of the function)
var mongodb = require('mongodb')
function getlastelements(ID){
return new Promise(function(resolve, reject){
var MongoC = mongodb.MongoClient;
var url = 'mongodb://localhost:27017/Weatherdb';
MongoC.connect(url, function(err,db){
var collection = db.collection('datas');
collection.find({"ID" : String(ID)}).sort({_id:-1}).limit(10)
.toArray(function(err, cursor){
if(err) reject(err)
resolve(cursor.length)
db.close()
})
})
});
}
getlastelements(1).then(result => console.log(result)).catch(err => console.log(err)
Javascript Promises

Related

Unable to retrieve data from MongoDB in Express

I am trying to write a simple code to fetch some data from MongoDB in express.
Below is my code:
var MongoClient = require('mongodb').MongoClient
var url = 'mongodb://localhost:27017/mcart'
MongoClient.connect(url)
.then(function (db) {
console.log(db)
})
.catch(function (err) {})
This gives me a JSON. But, when I try to access data from it, I get an error "db.collection" is not a function
var MongoClient = require('mongodb').MongoClient
var url = 'mongodb://localhost:27017/mcart'
MongoClient.connect(url)
.then(function (db) {
var cursor=db.collection("product_catalog").find();
cursor.each(function(err, doc) {
console.log(doc);
});
})
.catch(function (err) {console.log(err)})
Where am I going wrong?
Use hasNext(). It will move to the next doc in the cursor until it reaches to the end. Also get the database name before querying the collection
var DbName = db.db("databaseNameHere");
var cursor = DbName.collection("product_catalog").find();
while (cursor.hasNext()) {
console.log(tojson(cursor.next()));
}
Change your code to:
var MongoClient = require('mongodb').MongoClient
var url = 'mongodb://localhost:27017/mcart'
MongoClient.connect(url)
.then(function (db) {
console.log("Before")
var DbName = db.db("databaseNameHere");
var cursor=DbName.collection("product_catalog").find();
while (cursor.hasNext()) {
console.log(tojson(cursor.next()));
}
console.log("after")
})
.catch(function (err) {})
As you are using ^3.0.x this is the way to connect and execute queries.
Using MongoDB nodejs driver with version ^3.0.x gives you client object as callback function argument.
MongoClient.connect('mongodb://localhost:27017', (err, client) => {
if(err)
throw err
// Client returned
var db = client.db('mcart');
db.collection("product_catalog").find();
...
});
The way you're doing is the old way, used in 2.x version where it gives you db object as an argument to the callback function.
Read more about the change logs here
I tried the below code and this is working fine. This code is basically a combination of the other two answers. Just posting it for others in future.
var MongoClient = require('mongodb').MongoClient
var url = 'mongodb://localhost:27017'
var databaseName="mcart";
MongoClient.connect(url)
.then(function (mongoClientInstance) {
var database = mongoClientInstance.db(databaseName);
var x=database.collection("product_catalog").find().toArray();
return x;
})
.then(x=>console.log(x))
.catch(err=>console.log(err))

TypeError: Cannot read property 'collection' of null ---node to insertData with mongoDb

this is my problem. now the code is below
var mongoClient = require('mongodb').MongoClient;
var db = 'mongodb://localhost:27017/lcl';
var insertData = function(db,callback){
var collection = db.collection('user');
var data = [{"name":"lcl","age":"23","sex":"男"},{"name":"王小猫","age":"22","sex":"女"}];
collection.insert(data,function(err,result){
if (err) {
console.log(err);
return;
};
callback(result);
})
}
mongoClient.connect(db,function(err,db){
console.log("连接成功");
insertData(db,function(result){
console.log(result);
db.close();
})
})
above is the code I have written.
Please help me find the solution.
Try something like this. Check your Db and collections name.
var mongoClient = require('mongodb').MongoClient;
var db_config = 'mongodb://localhost:27017/conapp';
var insertData = function(db_config,callback){
var collection = db_config.collection('users');
var data = [{'username':'ddaaaa'}];
collection.insert(data,function(err,result){
if (err) {
console.log(err);
return;
};
callback(result);
})
}
mongoClient.connect(db_config,function(err,db_config){
insertData(db_config,function(result){
console.log(result);
db_config.close();
})
})
From official documentation:
callback (function) – this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the initialized db object or null if an error occured.
Logically you have to check for an error existence first and only then perform some operations on db

Putting MongoDB queries, inserts and removes in module.exports or exports

Is there a way to put MongoJS/Mongoose queries, inserts and removes in module.exports while getting an confirmation object back?
server.js
var mongoq = require('./models/mongoq.js');
var result = mongoq.connectToServer();
console.log(result);
mongoq.js
var mongojs = require('mongojs');
db = mongojs('config', ['questions']);
module.exports = {
//var answer;
connectToServer: function(){
db.questions.find(function (err, docs) {
return docs;
}
//return answer;
};
The result variable returns undefined, and if I put the return outside of a query, it wants to send it before doing the query.
Is there a way that I can force the module.exports to wait for the query before returning it?
Thank you
You can achieve this by my making use of a callback. I.e. you call the module from the other file with a function as parameter, this function has the result variable as parameter. This function will be executed when the query has completed.
server.js
var mongoq = require('./models/mongoq.js');
mongoq.connectToServer(function(result) {
console.log(result);
});
mongoq.js
var mongojs = require('mongojs');
db = mongojs('config', ['questions']);
module.exports = {
connectToServer: function(callback) {
db.questions.find(function (err, docs) {
callback(docs);
});
}
};

Nodejs - Why my variable in class is undefined?

In crawler.js :
var async = require('async');
var request = require('request');
var cheerio = require('cheerio');
var Helper = require('./helper.js');
var helper = new Helper();
var Crawler = function(){
var me = this;
this.listCategory;
this.getCategory = function(){
//1. not use async : test key input is idMenu
helper.categoryInMenu(1, function(err, result){
me.listCategory = result;
});
//2. use async : test key input is idMenu
async.map([1], helper.categoryInMenu, function(err, result){
me.listCategory = result;
//console.log(result);
});
console.log(me.listCategory); // return undefined
}
}
module.exports = Crawler;
When i set me.listCategory = result; (with result != null) then call listCategory in file main.js or console.log it in file crawler.js.
Display in command is undefined.
File main.js
var Crawler = require('./crawler.js');
var snipper = new Crawler();
snipper.getCategory();
console.log(snipper.listCategory);
I try use async module with function map, it not work.
Maybe, i not set me.listCategory = return of function helper.categoryInMenu.
File helper.js
var db = require('mysql');
var config = require('./configLoader.js');
config.load(__dirname+'/config.json');
var Helper = function(){
var me = this;
this.conn = db.createConnection(config.get('db'));
this.menu = function(callback){
me.conn.query("SELECT * FROM `menu`", function(err, rows){
callback(err, rows);
});
}
// return list category with "input" is a idMenu
this.categoryInMenu = function(idMenu, callback){
me.conn.query("SELECT * FROM `category` WHERE idMenu = ?", idMenu, function(err, rows){
callback(err, rows);
});
}
// return config of Category with "input" is a idCategory (Category)
this.dom = function(idCategory, callback){
me.conn.query("SELECT * FROM `category` WHERE id = ?", idCategory, function(err, rows){
callback(err, JSON.parse(rows[0].dom));
});
}
}
module.exports = Helper;
Map in all languages is used to transform the values of iterable into something else, that is why you should return in the callback function and the result will be new array containing only the returned values. If you need to iterate only, you should use arr.forEach (>ES5) or simple for loop.
Your problem is that async.map is asynchronous which means console.log(me.listCategory); is executed before the actual map.
Array.map is actually ES5 standard so you don't need async module to map arrays, also the native map is synchronous.

Connect synchronously to mongodb

I would like to connect to mongodb first, then run everything else in my application.
To do it I have to write something like:
MongoClient.connect("mongodb://localhost/test", function(err, connection) {
if (err) { console.error(err); }
db = connection;
var app = express();
// Include API V1
require("./apiv1.js")(app, db);
app.listen(3000, function(err) {
if (err) { console.error(err); } else { console.log("Started on *:3000"); }
});
});
This makes my app to be completely indented inside the .connect function... Which looks ugly and takes space while I work on my project.
I think the best solution would be have the MongoDB connection synchronous (even because witout the DB connection my app cannot work so why should I do something while it's connecting?) and then run the rest of my code.
How can I do?
You can't connect to MongoDB synchronously, but you may get rid of this ugly callback from your code.
The best way to do it is to adopt some wrapper around node-mongodb-native driver.
Take a look at the following modules.
mongojs
var mongojs = require('mongojs');
var db = mongojs('localhost/test');
var mycollection = db.collection('mycollection');
mongoskin
var mongo = require('mongoskin');
var db = mongo.db("mongodb://localhost:27017/test", {native_parser:true});
monk
var monk = require('monk');
var db = monk('localhost/test');
var users = db.get('users')
Of course, internally all of them are establishing MongoDB connection asynchronously.
Using the async library, you can aleve some of these issues.
For example in my server startup I do the following :
async.series([
function(callback){
// Initialize the mongodb connection and callback on completion in init.
db.init(function(){
callback();
});
},
function(callback){
// Listen on requests etc.
webServer.init(function(){
callback();
});
},
function(callback){
// Set up anything else that I need
callback();
}
]);
If you are using Node 6 and up versions, you can do something like this:
const MongoClient = require('mongodb').MongoClient;
const url = 'mongodb://localhost:27017/mydb';
let db = null;
getdb();
//your code
async function getdb() {
db = await MongoClient.connect(url);
}
Bring the mongodb library.
Declare the url constant .
Declare the variable db as null.
Call the getdb function.
Create the getdb function which has firt the async word
Assign to the db variable the result of the connection with the key word await.
You can do it with thunky, thunky executes an async function once and caches it, the subsequent calls are returned from the cache.
const MongoClient = require('mongodb').MongoClient;
const thunky = require('thunky');
var connect = thunky(function(cb){
let url = 'mongodb://localhost:27017/test';
MongoClient.connect(url, function(err, client){
console.log('connecting')
cb(err, client);
})
})
connect( (err, client) => {
console.log('connection 1')
})
connect( (err, client) => {
console.log('connection 2')
})
connect( (err, client) => {
console.log('connection 3')
console.log('closing')
client.close();
})
*Note: I am using latest 3.x mongodb driver

Resources