Pass model object to mongoose request - node.js

I would like to save an object from one schema to the array in another one. What I have is User schema and Events schema. User schema has, for example, a property "joined" which is array. When making put request, meeting should be pushed to "joined" array.
At the moment I have this code on clientside:
<div ng-repeat="event in events">
...
<button ng-click="joinEvent(event)">Join</button>
</div>
$scope.joinEvent = function(event){
$http.put('/join', event)
.success(function (data) {
$scope.users = data;
})
.error(function (data) {
console.log('Error: ' + data);
})
};
and this this in express.js routes:
app.put('/join', function (req, res){
var user = req.user; // logged in user
var id = req.user._id;
var update = { $addToSet: {joined: req.event} };
User.findByIdAndUpdate(id, update, {upsert: true}, function (err, user) {
if (!err) {
console.log("joined");
//return all users from db
User.find(function(err, users) {
if (err)
res.send(err)
res.json(users);
});
} else {
if(err.name == 'ValidationError') {
res.statusCode = 400;
res.send({ error: 'Validation error' });
} else {
res.statusCode = 500;
res.send({ error: 'Server error' });
}
console.log('Internal error(%d): %s',res.statusCode,err.message);
}
});
});
After all, I see 'null' in user.joined. What's wrong with my approach?

The way you're trying to get the event name is wrong.
In your code, req.event == null . That's why you see null in 'user.joined'.
In the client - event property should look like this:
event = {eventName: "someEventName"}
In the server - you reach to event name like this:
var update = { $addToSet: {joined: req.body.eventName} };

Thanks to Yarden for pushing me into the right direction. I made it in other way by passing event id on clientside and making Event.findById query before looking for user. That worked.

Related

Cannot set headers after they are sent to clients in node.js

My code is not working . I am beginner and don't know my problem. Kindly help.I have seen one or two solution on stackoverflow but didnot get .
This is code.
app.post('/post',(request,response)=>{
var description=request.body.description;
var contact_number=request.body.contact_number;
var city=request.body.city;
var budget=request.body.budget;
var category=request.body.optradio;
var query=connection.query("insert into jobs(Jobs_id,Description,Category,City,Contact_number,Budget) values(?,?,?,?,?,?)",[null,description,category,city,contact_number,budget],function(err){
if(err)
console.log(err);
else
response.send("successful");
});
response.redirect('/data');
});
app.get('/data',function(request,response){
connection.query("SELECT * FROM jobs ORDER BY Jobs_id DESC",(err, rows,fields) => {
if(err) {
console.log(err);
}
else {
response.render('feed', {title : 'Jobs Details',
items: rows })
}
});
});
app.listen(3000);
This is the error
pp.post('/post', (request, response) => {
var description = request.body.description;
var contact_number = request.body.contact_number;
var city = request.body.city;
var budget = request.body.budget;
var category = request.body.optradio;
var query = connection.query("insert into jobs(Jobs_id,Description,Category,City,Contact_number,Budget) values(?,?,?,?,?,?)", [null, description, category, city, contact_number, budget],
function (err) {
if (err) {
console.log(err);
} else {
response.redirect('/data');
}
});
});
app.get('/data', function (request, response) {
connection.query("SELECT * FROM jobs ORDER BY Jobs_id DESC", (err, rows, fields) => {
if (err) {
console.log(err);
}
else {
response.render('feed', {
title: 'Jobs Details',
items: rows
})
}
});
});
app.listen(3000);
There can be only one response to single HTTP request. In your code, you are first trying to send response with
response.send("successful");
but this on its own doesn't break the flow of the function which means that if the condition is actually met then this will execute and the execution continues and finds another response, in this case
response.redirect('/data');
and it will try to send another response to the original http request but at this point it is already too late because one response has already been send.
To solve this issue in general, you can place return in front of any line of code that is closing the the connection (response.send, response.redirect, ...). That way, the function's execution is terminated at the first response, whichever it is.
So you could do something like
var query=connection.query("insert into jobs(Jobs_id,Description,Category,City,Contact_number,Budget) values(?,?,?,?,?,?)",[null,description,category,city,contact_number,budget],function(err){
if(err)
console.log(err);
else
return response.send("successful");
});
return response.redirect('/data');
});

how to store response public api array in database

I have created API,to get the pincode related area details. When I enter pincode it shows area details of that pincode , if that detail exist in my databse. But sometimes that pincode related details are not available in my database, so i need to call it by public API and also store that passed pincode and area details in my database. In Command prompt i am getting response,of PostOffice array. So the details which I am getting needs to be stored in Database. How can I do that?
I am able to store pincode which I am passing in API , and in other fields such as Name,Description etc. runturns as empty[] in database.
I am using mlab for it
Changed code: i am able to store pincode & i need to store array result,on cammand prompt displaying the body,includes the PostOffice array,in which having Name,Description,Branchtype...etc I need to store all this field.schema contains this fields.
router.get('/pincode/:pincode',function(req, res) {
Pincode.find({pincode : req.params.pincode},function(error,pincode ){
//when pincode not found in db
if(pincode.length == ''){
console.log("gfhg");
function searchAndSave(pincode, callback){
var request = require('request');
res.statusCode = 302;
request('http://postalpincode.in/api/pincode/'+pincode,function (error, res, body) {
if (res.statusCode === 200) {
var pincodeData = new Pincode({
pincode:pincode,
body:body.PostOffice
});
pincodeData.save(function (err,results) {
if (err) {
return callback(err);
}
else {
console.log(body);
return callback(null,pincodeData);
}
});
}else
//no record found
return callback(null,null);
}
});
}
searchAndSave(req.params.pincode,function(errInSearchAndSave,result){
if(errInSearchAndSave){
console.log("error : ", errInSearchAndSave);
}else{
//pincode result return from api and db
res.json(result);
}
})
}else{
//pincode found in db
res.json(pincode);
}
});
});
Your have to check if result found in db or not and create separate callback function for better clarification
//create a seprate function for search and store db
function searchAndSave(pincode, callback){
var request = require('request');
res.statusCode = 302;
request('http://postalpincode.in/api/pincode/'+pincode,function (error, res, body) {
if (res.statusCode === 200) {
var pincodeData = new Pincode({
pincode:pincode,
body:body.PostOffice.Name
});
pincodeData.save(function (err,results) {
if (err) {
return callback(err);
}
else {
console.log(body);
return callback(null,pincodeData);
}
});
}else{
//no recoord found
return callback(null,null);
}
}
router.get('/pincode/:pincode',function(req, res) {
Pincode.find({pincode : req.params.pincode},function(error,pincode ){
//when pincode not found in db
if(!pincode){
searchAndSave(req.params.pincode,function(errInSearchAndSave,result){
if(errInSearchAndSave){
console.log("error : ", errInSearchAndSave);
}else{
//pincode result return from api and db
res.json(result);
}
})
}else{
//pincode found in db
res.json(pincode);
}
});
});

Unable to find record by id in mongoose

I am trying to find record by id but it not getting done
var id = req.param('id');
var item = {
'_id': id
}
videos.find(item, function(error, response) {});
I have give a valid id but still it is not fetching,can anyone suggest help,please.
There is a callback provided to find() but in your code above, it has no executable statements. Instead of this:
videos.find(item, function(error, response) {});
...do something like this:
videos.find(item, function(error, response) {
if (error) {
console.log(error); // replace with real error handling
return;
}
console.log(response); // replace with real data handling
});
You have to use callbacks for error handling. And find() returns array. If you need to find user by unique key (in this case _id) you must use findOne()
router.get('/GetVideoByID/:id',function(req,res){
var id = req.params.id;
var video = {
'_id' : id
}
videos.findOne(video,function(err,data){
if(err){
console.log(err);
}else{
console.log("Video found");
res.json(data);
}
});
});

sending data from Javascript to save in mongoDB through nodejs

I am trying to parse an object from a javascript (a blog post head and body) through a node.js server and on to save it in the mongoDB.
this is the parsing code:
function saveState( event ) {
var url = '';
var postTitle = headerField.innerHTML;
var article = contentField.innerHTML;
var post = {
title: postTitle,
article: article
};
var postID = document.querySelector('.save').getAttribute('id');
if(postID != "new"){
url += "?id=" + postID
}
var request = new XMLHttpRequest();
request.open("POST", "draft" + url, true);
request.setRequestHeader("Content-Type", "application/json");
request.send(post);
}
this is sent to this node server handler:
app.post('/draft', routes.saveDraft);
exports.saveDraft = function(req, res){
var id = url.parse(req.url, true).query.id;
var post = db.getPostByID(id);
if(id){
console.log('post id' + id);
db.savePost(id, req.body.head, req.body.article);
}
else{
db.newPost(req.body.head, req.body.article);
}
res.render('editDraft.hbs', post); //send the selected post
};
and then, sent to one of these DB functions:
exports.newPost = function (postTitle, article) {
new postCatalog({title:postTitle,
_id:1,
author:'temp',
AuthorID:2,
date:'2/3/12',
inShort:article.substring(0,100),
content:article ,
published:false
}).save(function (err, login) {
if (err) {
return console.log('error');
}
else {
console.log('Article saved');
}
});
}
exports.savePost = function (id, postTitle, article) {
postCatalog.find({_id: id}).save(function (err, login) {
if (err) {
return console.log('error');
}
else {
console.log('Draft saved');
}
});
}
now, I just can't get this to work..
I am new to node and I could really use your help!
thanks
EDITED:
the parameters being sent to the DB saving functions were not written properly.
but i'm still stuck in the same place, where the data is being sent but not saved correctly. I think there's something wrong with my getPostByID function but I can't figure it out:
exports.getPostByID =function (id) {
var post = postCatalog.find({_id: id}, function(err, post){
if(err) {
return handleError(err);
}
else{
if(post > 0){
post = post[0];
}
return post;
}
});
return post;
}
I am using express (including bodyparser) and mongoose. view engine is hbs.
thanks again.
You have to write it the asynchronous way, e.g. your getPostByID:
exports.getPostByID = function (id, callback) {
postCatalog.find({_id: id}, function(err, post) {
if (err) {
callback(err);
}
else if (post && post.length > 0) {
callback(null, post[0]);
}
else {
callback(null, null); // no record found
}
});
};
And this is true for your whole code. It's totally different and the way you tried it will never work under Node.js.
BTW there is a mongo-driver method findOne which is better suited in this special case but I didn't want to change your code too much.

Return JSON data from a Mongoose document to client Javascript

I'm trying to return the JSON data in a mongoose document, and then display it using Angular. There's no errors on the page when using this code. The $http.get method in the Angular IndexCtrl never makes it to success, which leads me to believe the problem is how I'm implementing the API get method. Any help rewriting that method to return properly greatly appreciated!
To clarify: what I want is to be able to access the document like a JSON Object so I can display the data to the client.
update: it does produce the error:
GET http://localhost:3000/api/tracks
It takes a while for that error to show in the console
the api method
app.get("/api/tracks", function(req, res) {
return Track.find({}, function (err, tracks) {
if (err) {
res.send(500);
return;
}
return res.json({
tracks: tracks
});
});
});
the mongoose database
var mongoose = require('mongoose');
var uristring =
process.env.MONGOLAB_URI ||
'mongodb://localhost/HelloMongoose';
var mongoOptions = { db: { safe: true }};
var db = mongoose.createConnection(uristring, mongoOptions, function (err, res) {
if (err) {
console.log ('ERROR connecting to: ' + uristring + '. ' + err);
} else {
console.log ('Succeeded connected to: ' + uristring);
}
});
//a Schema for a track
var Schema = new mongoose.Schema({
name: String,
location: String,
description: String
});
var Track = mongoose.model('Track', Schema);
var spot = new Track({name: 'zildjian'});
spot.save(function (err) {
console.log('saved');
if (err) // ...
console.log('meow');
});
The Angular controller
function IndexCtrl($scope, $http) {
$http.get('/api/tracks').
success(function(data, status, headers, config) {
$scope.tracks = data.tracks;
console.log($scope.tracks + "scope tracks data"); //This does not log! it never makes it this far
});
}
The Jade template that displays $scope.tracks
p There are {{tracks.length}} posts
div(ng-repeat='track in tracks')
h3 {{track.name}}
div {{track.description}}
I was not pulling the entries from the model correctly. Here is how I fixed it:
app.get("/api/tracks", function (req, res) {
var track = [];
var Track = mongoose.model('Track', trackSchema);
Track.find({}, function (err, records) {
records.forEach(function (post, i) {
track.push({
id: i,
title: post.title,
text: post.text.substr(0, 50) + '...'
});
});
res.json({
track: track
});
});
};
}

Resources