ExpressJS re-query database after adding record to database - javascript

I'm new to expressJS and i'm wondering what is the best way to requery the database (mongo in my case) to get all the records after one is added.
exports.get = function (db) {
return function (req, res) {
var collection = db.get('notes');
collection.find({}, {}, function (e, docs) {
res.send(docs);
});
};
};
exports.create = function (db) {
return function (req, res) {
var title = req.body.title;
var note = req.body.note;
var collection = db.get('notes');
// Insert/update the note
collection.insert(
{
"title": title,
"note": note
},
function (err, doc) {
// If it failed, return error
if (err) {
res.send("There was a problem adding the information to the database. Error: "+err);
} else {
//res.redirect('/');
//res.json(db.get('notes'));
// WHAT IS THE BEST THING TO DO HERE TO GET ALL THE RECORDS INCLUDING THE ONE I'VE JUST ADDED?
exports.get(db);
}
}
);
}
};

I would replace
exports.get(db);
for
collection.find({}, {}, function (e, docs) {
res.send(docs);
});
The reason is that you are invoking this in the callback, AFTER the record has been inserted

Your exports.get function return a function, a kind of middleware I see.
Repplace
exports.get(db);
by
exports.get(db)();

Related

findByIdAndUpdate and push in mongodb issue ?

I am new to Mongodb and I am using findByIdAndUpdate which will update document but returning the old document ,
Here is my function ,
exports.createInner = function (req, res, next) {
console.log("req", req.body);
var innerFolderDetails = req.body.innerFolder;
Repository.findByIdAndUpdate(innerFolderDetails._id, {
$push: {
innerFolder: {
"foldername": innerFolderDetails.foldername,
"ismainFolder": innerFolderDetails.ismainFolder,
"parentfolderId": innerFolderDetails.parentfolderId,
}
}
}, function (err, response) {
if (err) return next(err);
console.log(response);
res.json(response);
});
};
findByIdAndUpdate can accept an options object as a third argument.
Model.findByIdAndUpdate(id, updateObject, {
new: true // get the modified document back
}, callback);
By default the value of new options is false

Mongodb find() return undefined

When ever I try to just use a simple find() for my mongodb it returns undefined.
var MongoClient = require('mongodb').MongoClient;
var url = 'mongodb://localhost:27017/local';
MongoClient.connect(url, function (err, db) {
db.collection('pokemon').find({ $search: { $text: 'Pikachu' } }).toArray(function(err, data){ console.log(data) })
});
EDIT:
Turns out I never created an index by putting
db.collection('pokemon').createIndex({Name: 'text'})
before all the code.
First of all, every time where you have:
function(err, data){ console.log(data) }
you should check errors:
function (err, data) {
if (err) {
console.log('Error:', err);
} else {
console.log('Data:', data);
}
}
Then you will probably see what's going on.
This is also true for the database connection itself - instead of:
MongoClient.connect(url, function (err, db) {
// use db here
});
you should handle errors:
MongoClient.connect(url, function (err, db) {
if (err) {
// handle errors
} else {
// use db here
}
});
If you don't handle errors then don't be surprised that you don't know why you don't get values.

Method name is not a function

I have problem in calling the method in my module.
There is an errorTypeError: usr.User.getAddress is not a function
I don't know how to fix this I think I have problem in my module code. I want to get the address or the result.
in my main.js
var mysql = require('mysql');
var usr = require('./user');
var useraddress = usr.User.getAddress (id,pool); //this is how I access the method
in my user.js
exports.User = function () {
return {
getAddress: function (userid, pool){
pool.getConnection(function (err, connection) {
var options = {
sql: " select address from user where id = ?
};
var querypos = connection.query(options, [userid], function (err, results) {
if (err) throw err;
});
});
}
};
};
You are exporting User as a factory function which returns an object with getAddress method on it. So you need to invoke (instantiate) User first:
var useraddress = usr.User().getAddress(id, pool);
Another important problem. connection.query request is asynchronous, which means that assigning getAddress result to var useraddress doesn't make sense. Instead you need to either pass callback to getAddress or use Promise pattern (check this post for great deal of details on the topic: How do I return the response from an asynchronous call?).
In your case I think something like this would be a simplest working approach:
exports.User = function () {
return {
getAddress: function (userid, pool){
pool.getConnection(function (err, connection) {
var options = {
sql: "select address from user where id = ?"
};
var querypos = connection.query(options, [userid], function (err, results, callback, errCallback) {
if (err) {
errCallback(err);
}
callback(results);
});
});
}
};
};
and usage:
usr.User().getAddress(id, pool, function(result) {
console.log('Loaded', result);
});
This is because usr.User does not have .getAddress property on it.
To use .getAddress as a property, you need to export User as an object instead.
exports.User = {
getAddress: function (userid, pool){
pool.getConnection(function (err, connection) {
var options = {
sql: " select address from user where id = ?
};
var querypos = connection.query(options, [userid], function (err, results) {
if (err) throw err;
});
});
}
};
};
Now it does.

creating a dynamically restful api for node.js

I'm using mongodb for pretty much everything in my node.js application, and now i want create a restful application, so, i did that:
I'm trying to do just the get method, for now:
restApi.js:
var restAPI = {
get: function(method, model, sort, limit, options) {
if (method !== 'get') {
return;
}
model.find(options).sort(sort).limit(3).exec(function (error, result) {
if (error) {
return error;
} else {
return result;
}
});
},
};
And now i can require this in my route:
var restApi = require('restApi');
and use like this:
app.get('/', function(req, res, next) {
var result = restAPI.get('get', Event, 'date', 3, {'isActive': true});
res.render('/', {
result: result
});
});
Is not working, the result is undefined. Why??
How can i transform this in a async function with callback? This is possible?
Thanks! :)
You're not returning anything from restApi.get. If you're using mongoose, you could return a Promise easily enough:
var restAPI = {
get: function(method, model, sort, limit, options) {
if (method !== 'get') {
return;
}
return model.find(options).sort(sort).limit(3).exec();
},
};
Then you can use it like this:
app.get('/', function(req, res, next) {
restAPI.get('get', Event, 'date', 3, {'isActive': true}).then( function ( result ) {
res.render('/', {
result: result
});
}).catch( error ) {
// Render error page and log error
});
});
It is because your model is async. You have to pass callbacks.
Using async way is better because it is not blocking your application while waiting for response.
Example on your case:
restApi.js:
var restAPI = {
get: function(method, model, sort, limit, options, cb) {
if (method !== 'get') {
return cb("Method must be GET");
}
model.find(options).sort(sort).limit(3).exec(function (error, result) {
if (error) {
return cb(error);
} else {
return cb(null, result);
}
});
},
};
And now i can require this in my route:
var restApi = require('restApi');
and use like this:
app.get('/', function(req, res, next) {
restAPI.get('get', Event, 'date', 3, {'isActive': true}, function(err, result){
if(err)
return res.render("Error:" + err)
res.render('/', {
result: result
});
});
});
I've added cb argument to your REST API function so it is called when model async operation is done.
Router handler passes it's callback and prints output when operation is finished.

expressJS : separating route, model, making exported properties from model to route to work async?

Im new to js/nodejs/express, and on my own tried to structure my file in an MVC like pattern
The problem is the console.log (at routes.js, the most important) returns undefined, while the second one returns the real data, and is executed by node respectively as well, How would I return that data in an async manner from my model to the route?
In my server.js
require('./modules/pos/routes')(app);
require('./modules/pos/models/inventory')(app);
In my routes.js
module.exports = function(app) {
Inventory = require('./models/inventory')(app);
app.get('/poss', function(req, res) {
var result = Inventory.get();
console.log('result1 is',result); // !
res.end(JSON.stringify(result));
});
}
In my inventory.js
module.exports = function(app) {
return {
get : function() {
var res;
app.conn.query('SELECT * FROM users', function(err, rows) {
res = JSON.stringify({users : rows});
console.log("result is ",res); // !
return res;
});
}
}
}
P.S executing node server in the terminal, and browsing to localhost:8000 gives
result1 is undefined
result is {"users":[{"id":1, "username": ...blah..
Your first console.log is executed before the second. And the get method doesn't return anything because the method that returns is the one inside the get. In order to make your method async add a callback, like this:
// inventory.js
module.exports = function(app) {
return {
get : function(cb) {
app.conn.query('SELECT * FROM users', function(err, rows){
if (err) {
return cb(err);
}
res = JSON.stringify({users : rows});
console.log("result is ", res);
cb(null, res)
});
}
};
};
// routes.js
module.exports = function(app) {
var Inventory = require('./models/inventory')(app);
app.get('/poss', function(req, res) {
Inventory.get(function (err, result) {
if (err) {
// do something else in case of error
return;
}
res.end(result); // you don't need to use json stringify here cause the result is serialized
});
});
}

Categories

Resources