'undefined is not a function' when using unordered bulk upsert - node.js

I am using a bulk upsert to update/add several documents at once to my database:
var bulk = collection.initializeUnorderedBulkOp();
docs.forEach(function(doc, index, array){
bulk.find({'docId' : doc.docId}).upsert().updateOne(doc);
});
bulk.execute();
On bulk.execute this is returning the following error:
/myPath/node_modules/mongodb/node_modules/mongodb-core/lib/topologies/server.js:771
catch(err) { process.nextTick(function() { throw err}); }
^
TypeError: undefined is not a function
at /myPath/node_modules/mongodb/lib/bulk/unordered.js:470:5
I have looked at the code in the mongodb module and it seems to be failing on the callback here:
// Execute batches
return executeBatches(this, function(err, result) {
callback(err, result);
});
The data is being written to the database exactly as expected, but this error is still being thrown, and I can't work out what I could be doing to cause it.
I have ruled out problems with my data by using trivial objects, and by using bulk inserts instead of upserts as they are simpler, but the results are the same.

You need to invoke bulk.execute with a callback.
bulk.execute(function(err,results) {
if(err)
console.error(err);
else
console.log(results);
});
Or the like, should work.

Related

Return 404 code in proper way instead empty array

I have an quite simple application the idea is that someone has unique code which value are stored in one mongo collection in other we are keeping some data which we need to return if the key was found in first collection.
As probably you have noticed I'm using NodeJS with MongoDB and Mongoose, Express.
I have a problem with method bellow:
exports.getCompanyByKey = function(req, res) {
console.log(req.params.keyvalue);
var query = Company.where({keyValue : req.params.keyvalue});
query.findOne(function(err, company){
if(err){
res.send(err);
}else{
SampleData.findOne({}, function(err, sample_data){
if(err)
res.send(err);
res.json(sample_data);
});
}
});
};
The problem is that it will always return the data beause it's not throwing an error but empty array - so is there any other good and proper way as it should be don to throw 404 error without statement such as if(length<0) res.status(404).send('Error message).
I simply want to minimalize amount of if statements.
Maybe there is some other way to write implementation od error handling for mongoose which in general instead returning empty array will give us error code with message?
It's not exactly clear what you're asking, but if you want to make an error condition out of something that is not normally an error, then an if statement (or some other test like that) is required to test for that specific condition.
You could make your own function for querying that turns an empty response into an error and you could "hide" the if condition in that function if you want, but it's still an if condition that tests for your specific condition.
So, to return a 404 if the array is empty, you would just add an if statement (as you already appear to know):
exports.getCompanyByKey = function(req, res) {
console.log(req.params.keyvalue);
var query = Company.where({keyValue : req.params.keyvalue});
query.findOne(function(err, company){
if(err){
res.status(500).send(err);
} else {
SampleData.findOne({}, function(err, sample_data){
if(err) {
res.status(500).send(err);
} else {
if (sample_data.length) {
res.json(sample_data);
} else {
res.status(404).send("no data");
}
}
});
}
});
};
FYI, you also need to make sure you are properly setting a status code when there's an error and that you are never sending multiple responses to the same request (even when there's an error). I've also fixed several cases of those issues in your code.
This could likely be written cleaner and responses consolidated by using the promise interface to your database and send an error in one .catch().
For example, you could simplify your code by creating a utility function for .findOne() that detects and sends an error response automatically:
function findOne(res, db, q, cb) {
db.findOne(q, function(err, data) {
if (err) {
res.status(500).send(err);
cb(err);
} else if (!q.length) {
res.status(404).send("no data");
cb(new Error("no data"));
} else {
cb(null, data);
}
});
}
Then, your function could be simplified to this:
exports.getCompanyByKey = function(req, res) {
var query = Company.where({keyValue : req.params.keyvalue});
query.findOne(function(err, company){
if(err){
res.status(500).send(err);
} else {
findOne(res, SampleData, {}, function(err, sample_data) {
// any error response has already been sent
if (!err) {
res.json(sample_data);
}
});
}
});
};
Again, this would be better to use your Db's promise interface.

CouchDB bulk copy operation doesn't send back callback

I'm using nano db library (also try this with cloudant ant library)
for node js
I have this sample code :
exports.insert = function (db_name, data, callback) {
var db_name=db_name; if(!db){ db = nano.use(db_name); } console.log(`try to make bulk copy to Couchdb`); db.bulk(data, function (err, body) {
if (!err) {
console.log(`data in db ${db_name} inserted successfully`);
return callback(null, body);
}
console.log(`err ouccre ${err}`);
return callback(err);
}); }
The "data" variable is an object that contain the 'docs' property and
'docs' contain array.
I'ts always do the bulk work and put the docs array into my cloudnat
db , but
Often doesn't return any callback (err / success) to my node js
process
and it stuck...
Any suggestion?

MongoDB RangeError: attempt to write outside buffer bounds

I am not receiving this error all the time but for specifics arrays. I am trying to insert a JSON object into mongodb collection using node.js mongodb native driver. This JSON object has couple of string attributes and a big string array attribute. Array could have thousands of string items.
My JSON looks like this
{
FileName :"504-2345.txt",
SIMs :["8931440400012","893144040001","4000130360507",.........]
}
Any idea when MongoDB throws RangeError: attempt to write outside buffer bounds? Please suggest
Below method insert the data in Mongodb
Insert: function (data, type, callback) {
MongoClient.connect(url, function (err, db) {
// logger.log("info","Before Inserting documents into "+type +" documents =>"+data.length);
if (err) {
logger.log("error", err);
}
var collection = db.collection(type);
// Insert some documents
collection.insertOne(data, function (err, result) {
if (err) {
logger.log("error", " Error for Data while inserting Error =" + err);
}
else {
db.close();
if (result.ops) {
callback(err, result.ops[0]);
}
}
});
});
},
The document should be less than 16mb. Otherwise it get exceptions.You can refer this link for more details. You can use gridFs in here.

Is Error Trapping Data Returned by an Error-First Callback a Good Practice?

dataObject.query(err, data){
if(!data){return;}
else if(err){console.log("There is an error");}
else{console.log(JSON.stringify(data));}
}
The author of Getting MEAN with Mongo, Express, Angular, and Node features a code segment in a API controller that is similar to the code above. Is the error trapping conducted in the first if statement for the "data" object necessary, considering the fact that the callback function already features an err object?
If (!data) == true then it means there is no data received from the query. This is not an error, but just a query with 0 results (and as you can see no error is logged to console).
However the correct way to check is to flip the order between the first 2 conditions:
dataObject.query(err, data){
if(err) { console.log("There is an error"); } // If there's an error from the query then log it.
else if(!data) { console.log("There's no data"); } // If the result is empty (no data) then log that there's no data. (It is better to return a false value or some other indication that there was no result).
else { console.log(JSON.stringify(data)); } // Finally, if there are results and no errors, log them as a string (pay attention that I've also fixed that function).
}
Normally you check error first:
function (err, data) {
if (err) {
return callback(err);
}
}
Then you can check data, if it still can be missing. You can just short-circuit your function or call callback with a new error:
function (err, data) {
if (err) {
return callback(err);
}
if (!data) {
return callback(new Error('No data.')); // or callback(null, data) or something like that
}
}
Doing that in a different order makes no sense as in case of error data would be most likely missing.

mongodb native how to work with query

I'm trying to retrieve data from my mongolab DB using Node-mongodb-native
var findAll = function () {
var ddocs;
collection.find({}).each(function (arr, docs) {
ddocs = docs;
});
console.log(ddocs);
};
But it seems that when I log ddocs, it will give me undefined, but if I log docs it will show me the data.
Please help
How should I use this function ?
Thanks
Tzelon Machluf
You're basically trying to create a function that will return all of the documents in a collection? If so, the below should do work. However, I agree with #hgoebl and that you should work on your understanding of node as this is not likely the best way to accomplish what you're trying to do.
var ddocs;
var findAll = collection.find().toArray( function(err, docs) {
if(err)
throw err;
console.log('Collection returned');
return ddocs = docs;
});
setTimeout( function(err) {
if(err) throw err;
console.log(ddocs);
db.close();
}, 1000);
One thing in particular to note: collection.find is asynchronous, so the problem in your code (why it says ddocs is undefined) is that you're logging ddocs before the collection.find ever finished; thus, it's initialized, but no assigned any values. The Node convention is to nest callbacks so that everything happens in the right order and when it's ready.

Resources