I am using node-mongodb-native in my application. I send multiple POST requests to nodejs server to save/update each documents, but only one document is getting updated and all other document are not changing. The data received in the server is correct.
save : function(req,res) {
data = req.body;
if(!data._id){
data._id = new ObjectID();
}else{
data._id = ObjectID(data._id);
}
mColl(req.params.collname, function (collection,db) {
collection.save(data, {safe:true}, function(err, result) {
if(err){
res.send(err);
}
else {
res.send(result);
}
});
});
}
I am not getting the response for the request also.
For starters, don't do this:
data = req.body;
When a new request comes in, you're overwriting the (global!) data variable, and all kinds of undefined stuff can happen. So always declare a new variable:
var data = req.body;
Related
I'm creating a RESTful API.
I wanna use GET method to check if lastName exists. If it can find lastName, return "YES", otherwise, call a POST method to create a data with lastName entered.
The problem is that it can create a new data, but the body is empty. Ideally, it should contain a value with lastName, like "lastName": "James",
{
"_id": "58a22c3c3f07b1fc455333a5",
"__v": 0
}
Here is my code.
router.route("/findLastName/:id")
.get(function(req,res){
var response;
mongoOp.findOne({deviceID: req.params.id}, function(err, result){
if (err) {
response = {"error" : true,"message" : "Error fetching data"};
res.json(response);
}
if (result) {
response = "YES";
res.send(response);
} else {
var XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest;
var xhr = new XMLHttpRequest();
var POSTurl = "http://localhost:6002/users";
var params = "lastName=" + req.params.id;
xhr.open("POST", POSTurl, true);
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.send(params);
}
});
})
PS: GET method works well, not a issue.
Let me modify a bit of your code and add comments as pointers:
// changed findLastName to find-last-name. It's a common convention,
// urls need to be case insensitive. It doesn't concern lastName, as
// that's a parameter, internal to your app so it's fine.
// even better if you name the route `find-or-create` or something, to better
// reflect what you're doing.
router.route("/find-last-name/:lastName")
.get(function(req,res){
var response;
mongoOp.findOne({deviceID: req.params.lastName}, function(err, result){
if (err) {
response = {"error" : true,"message" : "Error fetching data"};
// Adding a `return statement here. If you don't return, you'll tell
// the user that there was an error, but your code continues running
// potentially calling that res.json twice.
// Also, since it's an internal error, it's common to tell the client
// about it, by setting the status to 500
return res.status(500).json(response);
}
if (result) {
// turning the message to JSON instead. You started that above,
// and for the sake of your clients (your frontend), it's
// better to stick to JSON. Also you can pass useful info, such as
// _id of the document.
// Again adding a `return` here, and then the rest of the code
// is nested one level less. not required, but some people like that.
response = {
message: "Last name exists."
};
return res.json(response);
}
// Here begins the new code. I'm typing what I can infer from your code,
// I don't know if your MongoDB driver looks like that exactly.
mongoOp.insert({
deviceId: req.params.lastName
// add other optional properties here.
}, function (err, response) {
if (err) {
var message = {
error: true,
message: 'Cannot save new entry.'
}
return res.status(500).json(message);
}
// if we're here, everything went ok. You can probably return
// the _id of the given user.
return res.json({
message: 'New user created.',
_id: response._id
});
});
});
})
I have following code to fetch some data from the db (mongo).
function getAllUsers(){
var UsersPromise = Q.defer();
UserSchema.find({}, function(err, data){
if(err){
UsersPromise .reject(err);
}else {
UsersPromise .resolve(data);
}
});
return UsersPromise .promise;
}
Then I modify each of these models. I add certain fields to the model depending on the type of user. (This is working correctly).
function buildUsers(users){
// my code iterates over users and adds
// properties as required.
// Working fine.
return users; // updated users.
}
Now I want to save these updated models back to mongo and this is where it's making me pull my hair.
function saveUsers(users){
// here, the users are received correctly. But the following line to save the users fails.
var SaveUsersPromise = Q.defer();
UserSchema.save(users, function(err, data){
if(err){
SaveUsersPromise .reject(err);
} else {
SaveUsersPromise .resolve(data);
}
});
return SaveUsersPromise .promise;
}
Lastly I call these functions like:
DB.connect()
.then(getAllUsers)
.then(buildUsers)
.then(saveUsers)
.catch(errorHandler);
Everything works correctly untill I call UserSchema.save. What could be the problem?
PS: I am using mongoose.
TIA.
UserSchema.save accepts single instance, you have to loop through users and save each. Mongoose doesn't have bulk inserts implemented yet (see issue #723).
Here's simple implementation using async.eachSeries
function saveUsers(users){
var async = require('async'); // <== npm install async --save
var SaveUsersPromise = Q.defer();
async.eachSeries(users, function(user, done){
UserSchema.save(user, done);
// or
user.save(done); // if user is Mongoose-document object
}, function(err){
if(err){
SaveUsersPromise.reject(err);
} else {
SaveUsersPromise.resolve();
}
});
return SaveUsersPromise.promise;
}
This may be a basic question but I've looked through the github Cloudant library and the Cloudant documentation and deleting a specific document from the database is mentioned but never thoroughly explained. It's very frustrating. The closest I've gotten to deleting a document is using an http request rather then the functions Cloudant library offers and I continuously get a "Document Update Conflict" even though I'm passing through the _rev of the document. Can anybody explain deleting a document from a Cloudant database using nodejs with an example to help sort this out. Thanks.
You can use the destroy method of nano like #JakePeyser has said, instead of using http APIs since you are using nodejs.
But since you are sending _rev and getting a "Document Update Conflict" error, it leads me to doubt if you have the latest _rev with you. "Document Update Conflict" happens mostly if the local _rev doesn't match the remote _rev. I would therefore suggest wrapping your destroy function in a get function. So an update to #JakePeyser's example would be:
var nano = require("nano")("cloudantURL"),
db = nano.db.use("yourDB");
db.get(docUniqueId, function(err, body) {
if (!err) {
var latestRev = body._rev;
db.destroy(docUniqueId, latestRev, function(err, body, header) {
if (!err) {
console.log("Successfully deleted doc", docUniqueId);
}
});
}
})
It depends what node module you are using for communicating with Cloudant. With the nano driver, you can use the destroy method to delete a document. See the following code example:
var nano = require("nano")("cloudantURL"),
db = nano.db.use("yourDB");
db.destroy(docUniqueId, docRevNum, function(err, body, header) {
if (!err) {
console.log("Successfully deleted doc", docUniqueId);
}
});
Key
cloudantURL - URL of your Cloudant instance, with username and password embedded
yourDB - your database name
docUniqueId - Unique ID of the doc you want to delete
docRevNum - Revision number of the doc you want to delete
Sample script to delete/destroy a doc from a collection "mytable" based on the value of the field "fkId".
var Cloudant = require('cloudant');
var Config = require('config-js');
var config = new Config('./settings.js');
var username = config.get('CLOUDANT_USER');
var password = config.get('CLOUDANT_PASWORD');
var cloudant = Cloudant({account:username, password:password});
var db = cloudant.db.use('mytable');
var key = 'fkId';
var value = '11234567890';
...
...
db.list({
'include_docs': true
}, function (err, body) {
/* istanbul ignore next */
if (err)
res.json({success: false, msg: 'Unable to fetch documents'});
else {
var rows = body.rows;
var items = [];
var rec_found = false;
rows.forEach(function (row) {
if (row.doc[key] === value) {
rec_found = true;
items.push(row.doc);
}
});
if (items.length === 0) {
console.log("No record found with fkId: "+ value);
res.json({success: true, msg: 'No record found with fkId: '+ value});
} else {
var docId = items[0]._id;
var docRev = items[0]._rev;
db.destroy(docId, docRev, function(err) {
if (!err) {
console.log("Successfully deleted doc with fkId: "+ value);
res.json({success: true, msg: 'Successfully deleted the item from the database.'});
} else {
res.json({success: false, msg: 'Failed to delete with fkId from the database, please try again.'});
}
});
}
}
});
I'm building a web application that will work with Big Data.
I will mine Twitter data using the Apache Storm, subsequently saving them in a MongoDB database.
At same time, this data has to be fetched via Node.js in real time and be sent via socket.io to my front-end.
Exist a way to querying MongoDB via Node.js in real time?
Thanks.
I am working on a project with mongoDB, I used the mongodb npm module to query the database in real time.
First I get a list of collections which are in my database:
//My server controller page
var MongoClient = require('mongodb').MongoClient
, assert = require('assert');
exports.getCollections = function(req,res){
mongoose.connection.db.collectionNames(function(err, names) {
if (err){
console.log(err)
} else {
res.status(200).send({collections: names});
}
});
};
On the front end, I do an Angular ng-repeat to list my collections, then when I click on the collection name, I run the following code:
MongoClient.connect(url, function (err, db) {
assert.equal(null, err);
var collection = db.collection(req.body.collName);
collection.find({}).limit(req.body.limit).toArray(function (err, docs) {
if (err) {
console.log(err)
} else {
res.status(200).send({r: docs, count: docs.length});
db.close();
}
})
});
Here is my client side angular code:
//get the collection list upon page load
$http.get('collections')
.success(function(c){
$scope.collList = c.collections;
})
.error(function(err){
$scope.error = err;
});
//function run when collection is selected
$scope.doFind = function(coll){
$scope.collViewing = coll;
$http.post('/basicfind',{collName: coll,limit:$scope.limiter})
.success(function(data){
$scope.results = data.r;
$scope.countOfResults = data.count;
})
.error(function(err){
$scope.error = err.message;
});
};
Hope that helps, let me know if you need me to share any more code
Through ajax request I have get the data form client and save it in mongodb database (mongoose) through save query .Now I want to know how to find data and display it new page.
I have get the data from client and save it in database. Now I want that when callback function calls it find data from the database and display it in new page using response.redirect.Please guide me.
$("#saveChanges5").live('click',function(){
var sendingObj = {
regOperation: $("#area_operation").val()
,regFieldAct: $("#field_activity").val()
,regOther: $("#other_details").val()
};
$.ajax({
url:'/WorkDetails'
,type:'post'
,data: sendingObj
,success:function(){
alert('Successfully saved')
},
error: function(){
alert("Saving Failed")
}
})
});
app.post("/WorkDetails",function(req ,res){
console.log(req.body);
saveWorkDetails(req.body.regOperation ,req.body.regFieldAct ,req.body.regOther ,function(){
res.send("");//here i want to add new code
});
});
function saveWorkDetails(area_operation ,field_activity ,other_details , callback){
console.log("save CALLED");
var receivedObj = new WorkDetailInfo({
area_operation:area_operation ,
field_activity:field_activity ,
other_details:other_details
});
console.log(receivedObj);
receivedObj.save(function(err){
console.log("inside Save ");
if(err){
//res.send(err);
console.log(err);
}
else{
callback();
}
});
}
You can make use of narwhal-mongodb APIs
Following is the example usage:
var MongoDB = require("mongodb");
var db = new MongoDB.Mongo().getDB("mydb");
var colls = db.getCollectionNames();
colls.forEach(function(el) { print(el); });
var coll = db.getCollection("testCollection");