I'm trying to get some data to save into MongoDb. I followed the following example beforehand and verified that it works, however now that I'm trying to write my own test app using this "format" it's not working. MongoDb does not throw any errors and I can even retrieve the doc _id from the insert callback. However when I go into the Mongo shell, the collection doesn't even exist let alone the document.
Here's the example I followed originally just so you can get a feel for the way I tried to mimic for my own test app:
http://blog.ijasoneverett.com/2013/03/a-sample-app-with-node-js-express-and-mongodb-part-1/
Below is my attempt that is failing. Thanks for any help!
Here's my DB code:
var Db = require('mongodb').Db,
Connection = require('mongodb').Connection,
Server = require('mongodb').Server,
BSON = require('mongodb').BSON,
ObjectID = require('mongodb').ObjectID;
Repository = function(host, port){
this.db = new Db('test-mongo-db', new Server(host, port, {safe: true}, {auto_reconnect:true}, {}));
this.db.open(function(){
console.log('db open');
});
};
Repository.prototype.getCollection = function(callback){
this.db.collection('owners', function(error, owners_collection){
if (error) callback(error);
else
callback(null, owners_collection);
});
};
Repository.prototype.createOwner = function(owner, callback){
this.getCollection(function(error, owners_collection){
if (error) callback(error);
else {
owners_collection.insert(owner, function(error, doc){
if (error) callback(error);
else {
console.log('insert was successful: ' + doc[0]['_id']);
callback(null, owner);
}
});
}
});
};
exports.Repository = Repository;
Here's the code that's calling it:
var Repository = require('../repositories/Repository').Repository;
exports.createOwner = function(req, res){
var owner = {
email : req.body.email,
password : req.body.password,
firstName : req.body.firstName,
lastName : req.body.lastName,
schools : []
};
var repository = new Repository('localhost', 27017);
repository.createOwner(owner, function(error, docs){
if (error) console.log('saving owner failed : ' + error);
else {
console.log('saving owner successful');
res.redirect('/');
}
});
};
If #cristkv is right, you can try to add optional parameter write concern in the insert operation:
owners_collection.insert(owner, {w:1}, function(error, doc){
sources:
http://mongodb.github.io/node-mongodb-native/2.0/api/Collection.html#insert
http://docs.mongodb.org/manual/core/write-concern/
Related
Hello I am new to building node js and express web applications and am trying to understand how to structure route handling + model code using MySQL and node.js. Here is an example of my current login.
router.post('/login', function (req, res, next) {
var email = req.body.email;
var password = req.body.password;
var sqlQuery = 'SELECT * FROM users WHERE email = ?';
checkUsername();
function checkUsername() {
connection.query(sqlQuery,[email], function (error, results, fields) {
if (error) return next(error);
if(results.length == 0) {
res.status(401).json({ message: 'invalid credentials' });
} else {
checkPassword(results[0].password, results[0]);
}
});
}
function checkPassword(hash, result) {
bcrypt.compare(password, hash, function(err, match) {
if (match) {
var userToken = jwt.sign({id: result.id}, config.JWTSecret, { expiresIn: '1h' });
delete result.password;
res.status(200).json({token: userToken, user_data: result});
} else {
res.status(401).json({ message: 'invalid credentials' });
}
});
}
});
as you can see currently all of the logic is being performed in the route handler. What is the advantage of extracting this code to a model object? Should the response be sent in the model or route handler? How would you structure your code for this particular example using a user object and more generally when using MVC with express and MySQL?
Thanks!
I am trying to load my data in the web api by using postman to test it out. So I am able to get my query right on console.log(doc) on node.js but when i tried to return callback and post on postman, it gives me [object Object]and does not give back the data itself just object. This is my code.
var MongoClient = require('mongodb').MongoClient;
var assert = require('assert');
var url = 'mongodb://localhost:27017/myproject';
module.exports = {
postCollection : function(req, res){
var issueQty = req.body.issueQty;
var itemDescrip = req.body.itemDescrip;
MongoClient.connect(url, function(err, db) {
assert.equal(null, err);
updateRecord(db, req, function(doc) {
res.send('Record Found. Now updating this document...' + itemDescrip + '
Record Updated. This is the new record '
+ doc )
db.close();
});
});
}
}
var updateRecord = function(db, req, callback) {
var cursor = db.collection('documents').find({'Item Description':
req.body.itemDescrip, 'Issued QTY': req.body.issueQty})
cursor.each(function(err,doc){
assert.equal(err,null);
if(doc != err){
console.log('Successfully queried');
console.log(doc);
return callback(doc);
} else{
callback(doc);
}
});
db.collection('documents').updateMany(
{ 'Item Description': req.body.itemDescrip},
{
$set: { 'Issued QTY': req.body.issueQty }
}
/*function(err, results) {
console.log(results);
console.log('Done');
});*/
)};
So right now I am lost as to where I have done wrong to output [object Object] instead of the queried data. Any help is appreciated, thanks!
So I managed to find the answer looks like I had to use callback(JSON.stringify(doc));
for postman to be able to read it and output the query.
I am using Express.js for my app and mongodb for database (also mongodb Nativ driver).
I created a model with two functions, for getting posts and comments:
// Get single Post
exports.posts = function(id,callback){
MongoClient.connect(url, function (err, db) {
if (err) {
console.log('Unable to connect to the mongoDB server. Error:', err);
} else {
console.log('Connection established to', url);
var collection = db.collection('posts');
collection.find({psotId:id}).limit(1).toArray(function (err, result) {
if (err) {
return callback(new Error("An error has occured"));
} else {
callback(null,result);
}
db.close();
});
}
});
}
// Get post comments
exports.comments = function(id,callback){
MongoClient.connect(url, function (err, db) {
if (err) {
console.log('Unable to connect to the mongoDB server. Error:', err);
} else {
console.log('Connection established to', url);
var collection = db.collection('comments');
collection.find({postId:id}).toArray(function (err, result) {
if (err) {
return callback(new Error("An error has occured"));
}
else {
callback(null,result);
}
db.close();
});
}
});
}
and I created a route to show single post:
var post = require('../models/post');
//Get single post
router.get('/post/:postId',function(req,res, next){
var id = parseInt(req.params.postId);
post.posts(id,function(err,post){
if(err){
console.log(err)
}else{
post.comments(post[0].id,function(err,comments){
if(err){
console.log(err)
}
else{
res.render('blogPost',{post:post,comments:comments})
}
})
}
})
})
When I run this code I get this error:
TypeError: Object [object Object] has no method 'comments'
When I use this two function separately its work fine:
I mean like this :
var post = require('../models/post');
//Get single post
router.get('/post/:postId',function(req,res, next){
var id = parseInt(req.params.postId);
post.posts(id,function(err,post){
if(err){
console.log(err)
}else{
res.render('blogPost',{post:post})
}
})
})
//Get post comments
router.get('/post/1',function(req,res, next){
post.comments(1,function(err,comments){
if(err){
console.log(err)
}else{
res.render('blogPost',{comments:comments})
}
})
})
But when I use post.comments as callback for post.posts I get an error.
I wants know why this happening? After some research I couldn't find a solution and I an getting confused.
In your source code you have the following:
var post = require('../models/post');
//Get single post
router.get('/post/:postId',function(req,res, next){
var id = parseInt(req.params.postId);
post.posts(id,function(err,post){
if(err){
console.log(err)
}else{
post.comments(post[0].id,function(err,comments){
if(err){
console.log(err)
}
else{
res.render('blogPost',{post:post,comments:comments})
}
})
}
})
})
when you are calling post.posts you have a callback and there you have a return value which you called post (which it is the same variable name of var post = require('../models/post');
Basically change it in the callback like this:
var post = require('../models/post');
//Get single post
router.get('/post/:postId',function(req,res, next){
var id = parseInt(req.params.postId);
post.posts(id,function(err,posts){ //HERE changed post into posts
if(err){
console.log(err)
}else{
post.comments(posts[0].id,function(err,comments){
if(err){
console.log(err)
}
else{
res.render('blogPost',{post:posts,comments:comments})
}
})
}
})
})
EDIT: for better understanding I would change var post = require('../models/post'); into var postModel = require('../models/post'); SO it is much more understandable
EDIT 2: since he posted the real version code
Basically you have the same problem, line 37 of route.js is overriding the movie variable.
You have to call the variable that comes back form the callback with another name, for example movieslike you used to do in the other 2 above.
router.get('/m/:movieId',function(req,res, next){
var id = parseInt(req.params.movieId);
movie.get(id,function(err,movies){
if(err){
console.log(err)
}else{
movie.subtitles(movies[0].imdb,function(err,subs){
if(err){
console.log(err)
}
else{
res.render('moviePage',{movie:movies,subtitles:subs})
}
})
}
})
})
If you copy-pasted this from your source then its because you mispelled the method.
post.commencts
should be
post.comments
I'm using Express 3.4.7 and mongo. I register a new character into my mongo database and then I would like to have my page (route : /game) but I want to get the data of the mongodb (like the _id) of my character.
Here is my code :
exports.newGame = function(ip, db){
return function(req, res){
//req.body return all the field
if(req.body.name && req.body.class) {
db.connect(dbconnection, function(err, db){
if(err) throw err;
var collection = db.collection('test'),
insertObj = {
name : req.body.name,
class : req.body.class
};
collection.insert(insertObj, function(err, data){
if(err) throw err;
console.log(data);
res.render('player/index', data); //Here is my problem
});
});
} else {
res.render('home/new', {title : 'Donjon & Gradon - New', ip : ip});
}
}
};
I would like to have the /game page and passing data and db after the query to mongo is OK.
I don't know if I am clear.
Can you help me ?
Regards,
Arnaud
I'm having problems with saving a document in MongoDB in my Nodejitsu/MongoHQ app. Locally all works fine, but the MongoHQ db requires authentification and it fails with working user/pass (connecting to MongoDB shell with the same credentials works fine). Here is the function:
var update_user = function(user, callback) {
var client = new Db(db, new Server(host, port, {}));
var update = function (err, collection) {
collection.findOne({uid:user.id}, function(err, doc) {
if (err) { throw err; }
if (!doc) doc = { uid: user.id }
doc.img = user.img;
doc.name = user.name;
collection.save(doc, {safe: true}, function(err, doc) {
if (err) { throw err; }
callback(user);
});
});
};
client.open(function(err, client) {
if (err) { throw err; }
client.authenticate(user, pass, function(err, result) {
client.collection('users', update);
});
});
}
What I'm doing wrong here?
UPD: err parameter of authenticate method has the following value:
{ [MongoError: auth fails] name: 'MongoError', errmsg: 'auth fails', ok: 0 }
I checked the stored password & username again, they work for logging in the MongoHQ shell.
If your credentials are for an admin user account you must target the admin database in your authenticate call:
client.authenticate(user, pass, {authdb: 'admin'}, function(err, result) {
client.collection('users', update);
});