How to use .save method in mongo? - node.js

app.put('/app/modify/:_id', function(req, res) {
Collection.findById(req.params._id, function (err, blog) {
if (err) res.send(err);
if (req.body.text1) blog.text1 = req.body.text1;
if (req.body.text2) blog.text2 = req.body.text2;
if (req.body.text3) blog.text3 = req.body.text3;
if (req.body.text4) blog.text4 = req.body.text4;
if (req.body.text5) blog.text5 = req.body.text5;
Collection.save( function (err) {
if (err) send (err);
res.json({message: 'Blog Post Updated!'});
});
});
});
Taken help from this - PUT and DELETE - RESTful API Express MongoDB Mongoose
But getting error- http://localhost:8080/app/modify/59203c7d9532c34903000002 net::ERR_EMPTY_RESPONSE and Node server stops with an error 'Collection.save is not a function'.

Try it...
app.put('/app/modify/:_id', function(req, res) {
Collection.findById(req.params._id, function (err, blog) {
if (err) res.send(err);
if (req.body.text1) blog.text1 = req.body.text1;
if (req.body.text2) blog.text2 = req.body.text2;
if (req.body.text3) blog.text3 = req.body.text3;
if (req.body.text4) blog.text4 = req.body.text4;
if (req.body.text5) blog.text5 = req.body.text5;
blog.save( function (err,response) {
if (err) res.json(err);
res.json({message: 'Blog Post Updated!'});
});
});
});

Related

Nodejs Rest API with mongoose and mongoDB

I have this rest API on nodejs as follows
router.route('/api/Customers')
.post(function(req, res) {
var Customer = new Customer();
Customer.name = req.body.name;
Customer.save(function(err) {
if (err)
res.send(err);
res.json({ message: 'Customer created!' });
});
})
.get(function(req, res) {
Customer.find(function(err, Customers) {
if (err)
res.send(err);
res.json(Customers);
});
});
router.route('/api/Customers/:Customer_id')
.get(function(req, res) {
Customer.findById(req.params.Customer_id, function(err, Customer) {
if (err)
res.send(err);
res.json(Customer);
});
})
.put(function(req, res) {
Customer.findById(req.params.Customer_id, function(err, Customer) {
if (err)
res.send(err);
Customer.name = req.body.name;
Customer.save(function(err) {
if (err)
res.send(err);
res.json({ message: 'Customer updated!' });
});
});
})
.delete(function(req, res) {
Customer.remove({
_id: req.params.Customer_id
}, function(err, Customer) {
if (err)
res.send(err);
res.json({ message: 'Successfully deleted' });
});
});
How can I create endpoints for specific fields ? For example if I want to GET results for CustomerName, CustomerZip, etc .. Do I have to create separate end points for each field?
Are you using express.js as framework? In this case you can put optional params in your route, for example:
router.route('/api/Customers/:Customer_id?')
.post(function(req, res) {
...
})
.get(function(req, res) {
...
});
});
in this way :Customer_id will be optional and you can manage logic inside your route.
This is a working example:
app.route('/test/:param1?/:param2?')
.get( function(req, res, next) {
res.json({
'param1' : req.params.param1,
'param2' : req.params.param2
});
});
app.listen(8080);
this route supports:
/test
/test/1
/test/1/2
inside response you can see value of this params, I don't know how pass only param2 without param1.

Why my nodejs requests are slow?

Im new in nodejs, and Im trying to learn by creating an app that has a list of users, that I can add and remove those users. Im using angularjs in frontend to send request to nodejs and after that to mongodb. The problem is that, if I click a lot of times in the button "adduser" a lot of times, my app goes slow.
To interact to mongodb I use:
app.get('/users',function (req, res) {
mongoose.model('Usuario').find(function (err, list) {
res.send(list);
});
});
app.post('/addusuario', function (req,res) {
var usuario = new Usuario(req.body);
usuario.save(function (err) {
if (err) {
console.log(err);
} else {
console.log('Usuario salvo com sucesso');
}
}); });
app.delete('/delusuario/:id', function (req, res) {
var id = req.params.id;
mongoose.model('Usuario').findByIdAndRemove(id , function(err) {
if(err) {
console.log(err);
} else {
console.log('Usuario removido com sucesso!');
}
});
});
Im my angularapp:
app.controller('AppCtrl', function($scope, $http, Data) {
function reload() {
Data.get('users').then(function(data){
$scope.usuarios = data;
console.log(data);
});
};
$scope.addUsuario = function(usuario) {
Data.post('/addusuario', usuario);
reload();
};
$scope.deletarUsuario = function(id) {
Data.delete("/delusuario/"+id).then(function(result) {
});
reload();
};
reload();
});
I dont know why it is becaming slow after I click to add user more than 3 times..
What I see in your code that you are not sending an response back to the user, you should do something after insert or delete in the database. res.end();
You should rewrite your code in the following way:
app.get('/users',function (req, res) {
mongoose.model('Usuario').find(function (err, list) {
res.send(list);
});
});
app.post('/addusuario', function (req,res) {
var usuario = new Usuario(req.body);
usuario.save(function (err) {
if (err) {
console.log(err);
res.json({err: err});
} else {
res.json({ok: true});
console.log('Usuario salvo com sucesso');
}
}); });
app.delete('/delusuario/:id', function (req, res) {
var id = req.params.id;
mongoose.model('Usuario').findByIdAndRemove(id , function(err) {
if(err) {
console.log(err);
res.json({err: err});
} else {
res.json({ok: true});
console.log('Usuario removido com sucesso!');
}
});
});
You block the stack by not returning the response to the client. And this is most probably the cause of your slow request.

Mongoose create method has no respond

There's no respone for below save method. I wonder why.
app.post('/something', function (req, res) {
mainModel.save(req.body.data ,function(err,data){
if(err){
console.log(err)
}else{
console.log(data)
}
});
});
Here's how my models/main.js look like http://pastebin.com/eQSFXWb5
You didn't return any response after save. you should return response ie. return res.status(400).send().
you can try it
app.post('/something', function (req, res) {
if(!req.body.data) {
return res.status(400).send({masg: 'Invalid data'});
}
var newMainModel = new mainModel(req.body.data);
newMainModel.save(function(err,data){
if(err){
console.log(err)
return res.status(400).send({masg: 'Error occurred'});
}
console.log(data);
return res.status(200).send(data);
});
});

Error: Can't set headers after they are sent nodejs

When I post the new event, it is created and the sort function works properly as well but when I call the search function, I want it to compare it with both name and location but it doesn't compare with location. Is there any way to check both? Also after sorting or search when I want to create a new event, it gives me the below error. I am new to this. Help me with both the errors.
server.js
var express= require('express');
var bodyParser= require('body-parser');
var morgan = require('morgan');
var config=require('./config');
var app= express();
var mongoose=require('mongoose');
var lodash= require('lodash');
var underscore= require('underscore');
//var User=require('./database/user')
mongoose.connect('mongodb://localhost:27017/db',function(err){
if(err){
console.log(err);
}
else{
console.log("connected!");
}
});
//res.json({message:" " })
app.use(bodyParser.urlencoded({extended: true })); //if false then parse only strings
app.use(bodyParser.json());
app.use(morgan('dev'));//log all the requests to the console
var api=require('./app/routes/api')(app,express,underscore,lodash);
app.use('/api',api);
app.get('*',function(req,res){
// res.sendFile(__dirname + '/public/views/index.html');
}); // * means any route
app.listen(config.port,function(err){
if(err){
console.log(err);
}
else{
console.log("The server is running");
}
});
api.js
var User= require('../models/user');
var Event=require('../models/event');
var config=require('../../config');
var secret=config.secretKey;
module.exports=function(app,express,underscore,lodash) {
var api = express.Router();
// app.use()
api.post('/signup', function (req, res) {
var user = new User({
name: req.body.name,
username: req.body.username,
password: req.body.password
});
user.save(function (err) {
if (err) {
res.send(err);
return;
}
res.json({
message: 'User created!'
});
});
});
api.get('/users', function (req, res) {
User.find({}, function (err, users) {
if (err) {
res.send(err);
return;
}
res.json(users);
});
});
/* api.get('search',function(req,res){
search: req.body.search;
if(search==)
});*/
api.post('/eventfeed', function (req, res) {
var event = new Event({
name: req.body.name,
location: req.body.location,
description: req.body.description,
price: req.body.price,
rating: req.body.rating
});
event.save(function (err) {
if (err) {
res.send(err);
return;
}
res.json({
message: 'Event created!'
});
});
});
api.get('/event', function (req, res) {
Event.find({}, function (err, event) {
if (err) {
res.send(err);
return;
}
res.json(event);
});
});
api.get('/sortby_price', function (req, res) {
Event.find({}, function (err, events) {
if (err) {
res.send(err);
return;
}
var ascending = true;//change to false for descending
events.sort(function (a, b) {
return (a.price - b.price) * (ascending ? 1 : -1);
});
res.json(events);
});
});
api.get('/sortby_rating', function (req, res){
Event.find({}, function (err, events) {
if (err) {
res.send(err);
return;
}
var ascending = true;//change to false for descending
events.sort(function (a, b) {
return (a.rating - b.rating) * (ascending ? 1 : -1);
});
res.json(events);
});
});
api.post('/search', function (req, res) {
Event.find({'name':req.body.name},function (err, events) {
if (err)
return res.json(err);
else
res.json(events);
});
Event.find({'location':req.body.name},function (err, events) {
if (err)
return res.json(err);
else
res.json(events);
console.log("name is" + req.body.name);
});
});
return api;
}
error
http_outgoing.js:335
throw new Error('Can\'t set headers after they are sent.');
^
Error: Can't set headers after they are sent.
at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:335:11)
at ServerResponse.header (c:\Users\MY LAPY\WebstormProjects\Main\node_modules\express\lib\response.js:718:10)
at ServerResponse.send (c:\Users\MY LAPY\WebstormProjects\Main\node_modules\express\lib\response.js:163:12)
at ServerResponse.json (c:\Users\MY LAPY\WebstormProjects\Main\node_modules\express\lib\response.js:249:15)
at Query.<anonymous> (c:\Users\MY LAPY\WebstormProjects\Main\app\routes\api.js:209:25)
at c:\Users\MY LAPY\WebstormProjects\Main\node_modules\mongoose\node_modules\kareem\index.js:177:19
at c:\Users\MY LAPY\WebstormProjects\Main\node_modules\mongoose\node_modules\kareem\index.js:109:16
at process._tickCallback (node.js:355:11)
In your /api/search route, you are performing two Event.find()s in parallel and inside the callback for each of those, you're responding to the same http request.
So you need to either:
Have a third callback that is called only when both Event.find()s have completed, so you respond to the request only once there, OR
Perform the Event.find()s sequentially by placing one inside the callback of the other and only respond to the request inside the inner-most callback, OR
Only perform one Event.find() by using $or to check either field. For example:
api.post('/search', function (req, res) {
Event.find({
$or: [ {'name': req.body.name}, {'location': req.body.name} ]
}, function (err, events) {
if (err)
return res.json(err);
else
res.json(events);
});
});

Express response doesn't work when using mongoose and async

I'm using express and mongoose. I have a weird issue when I'm using mocha test to run this endpoint.
exports.broadcastMessages = function(req, res, next) {
User.find({}, function(err, users) {
if(err) return next(err);
var push = function(user, callback) {
user.messages.push(req.body.message);
user.save(function(err) {
callback(err);
});
};
var fin = function(err) {
if (err) {
return next(err);
}
console.log('aaaaaaaaaa');
return res.send('ok');
};
async.each(users, push, fin);
});
};
Then I got a timeout error. There is only one user. So it's not a time issue. And I'm sure res.send('ok') was called. But when I removed user.save(). It worked...
exports.broadcastMessages = function(req, res, next) {
User.find({}, function(err, users) {
if(err) return next(err);
var push = function(user, callback) {
user.messages.push(req.body.message);
callback(err);
};
var fin = function(err) {
if (err) {
return next(err);
}
console.log('aaaaaaaaaa');
return res.send('ok');
};
async.each(users, push, fin);
});
};
I don't know why. Why added one more user.save() it doesn't work? res.send is called but no response.
The version of express is 3.4.7. Mongoose is 3.8.2.
When you say "I got a timeout error" do you mean mocha failed your test for taking too long? If so that is probably a problem in your mocha test itself not calling done() correctly. The above code looks OK to me and I think it should work. Some misc points:
Whenever you have this pattern:
user.save(function(err) {
callback(err);
});
You don't need that extra wrapper function that does nothing but call the callback. Just do:
user.save(callback);
Also, looping through the users and saving each one is much less efficient than just having mongodb do them all for you in a single command:
User.update({}, {$push: {messages: req.body.message}}, function (error) {...});

Resources