Node server crashes when trying to save mongoose document with unique index - node.js

I have a collection which has one of it's fields as a unique field.
var ProductSchema = new mongoose.Schema({
code: {type:String, required:true},
name: {type:String, default:""}
});
ProductSchema.index({ code: 1}, { unique: true });
When I create a new document with a code that already exists, the server crashes instead of returning an error through the callback:
module.exports.create = function (params, callback){
var product = new ProductModel(params);
product.save(function(error){
console.log(error);
callback(error);
});
}
Is this (the crash) the expected behavior or mongoose should be returning an error through the callback and not crash?
here's the error I get when saving the second document with same code:
[..path]/server/node_modules/mongoose/node_modules/mongodb/lib/mongodb/connection/base.js:245
throw message;
^
TypeError: Cannot read property '0' of undefined
at [...path]/server/node_modules/mongoose/node_modules/mongodb/lib/mongodb/collection/core.js:114:55
at [...path]/server/node_modules/mongoose/node_modules/mongodb/lib/mongodb/db.js:1132:7
at [...path]/server/node_modules/mongoose/node_modules/mongodb/lib/mongodb/db.js:1846:9
at Server.Base._callHandler ([...path]/server/node_modules/mongoose/node_modules/mongodb/lib/mongodb/connection/base.js:445:41)
at [...path]/server/node_modules/mongoose/node_modules/mongodb/lib/mongodb/connection/server.js:478:18
at MongoReply.parseBody ([...path]/server/node_modules/mongoose/node_modules/mongodb/lib/mongodb/responses/mongo_reply.js:68:5)
at null.<anonymous> ([...path]/server/node_modules/mongoose/node_modules/mongodb/lib/mongodb/connection/server.js:436:20)
at EventEmitter.emit (events.js:95:17)
at null.<anonymous> ([...path]/server/node_modules/mongoose/node_modules/mongodb/lib/mongodb/connection/connection_pool.js:201:13)
at EventEmitter.emit (events.js:98:17)

http://mongoosejs.com/docs/api.html#model_Model-save
Put an error handler on the save for the product directly:
ProductModel.on('error', function(){..});

Related

When creating a object from a model. the object is undefined

Hello for a project i need to log the export of .csv downloads.
I have searched a lot but still cannot find the answer.
I created a collection: 'tokens' in my mongoDB
The model is located in /src/models/token.coffee
the app is located in /src/app.coffee
controller located in /src/controllers/token.coffee
This is my model:
mongoose = require('mongoose')
timestamps = require('mongoose-timestamp')
enums = require './enums'
schema = mongoose.Schema
# Schema definition
TokenSchema = new schema
user:
type: mongoose.Schema.Types.ObjectId
ref: 'User'
required: true
first_name:
type: String
required: true
last_name:
type: String
required: true
status:
type: String
enums: enums.TokenStatuses.__values
default: enums.TokenStatuses.running
# Plugins
TokenSchema.plugin timestamps, createdAt: 'created_at', updatedAt: 'changed_at'
try
mongoose.model 'Token', TokenSchema
i call the following function from the controller:
create_tokens_record = (user_id) ->
User.findOne {_id: user_id}, (err, user) ->
obj =
user: user._id
first_name: user.first_name
last_name: user.last_name
token = new models.Token(obj)
console.log token
token.save (err) ->
return err if err
And the error is:
events.js:72
throw er; // Unhandled 'error' event
^
TypeError: undefined is not a function
at c:\Users\Daan\api\src\controllers\user.coffee:239:15
at Query.<anonymous> (c:\Users\Daan\api\src\node_modules\mongoose\lib\model.js:3435:16)
at c:\Users\Daan\api\src\node_modules\mongoose\node_modules\kareem\index.js:273:21
at c:\Users\Daan\api\src\node_modules\mongoose\node_modules\kareem\index.js:127:16
at process._tickDomainCallback (node.js:492:13)
I have no idea why my model is still undefined. Hope anyone can help me out!
I found the answer:
In my project there was a index.coffee where all the models were exported.
I forgot to add the newly created model to this file.

Getting Object.keys called on non-object when creating mongoose schema

I've done some research and tried few things, like dropping the collection etc. Nothing has helped.
Code:
MongoClient.saveData = function(schemaDefinition, data, collectionName){
console.log("Schema definition: "+schemaDefinition+" collection name: "+collectionName);
var RecordSchema = new mongoose.Schema(schemaDefinition);//{ Email: String, FirstName: String});//({any: Schema.Types.Mixed });
console.log("Schema created.");
var RecordModel = mongoose.model(collectionName, RecordSchema);
console.log("Model created. Inserting in batches.")
RecordModel.insertMany(data)
.then(function(mongooseDocuments) {
console.log("Insertion was successful.");
})
.catch(function(err) {
console.log("Error while inserting to DB.")
});
The error:
/home/ubuntu/ds_queuesystem/node_modules/mongoose/lib/schema.js:381
var keys = Object.keys(obj);
^
TypeError: Object.keys called on non-object
at Function.keys (native)
at Schema.add (/home/ubuntu/ds_queuesystem/node_modules/mongoose/lib/schema.js:381:21)
at new Schema (/home/ubuntu/ds_queuesystem/node_modules/mongoose/lib/schema.js:98:10)
at Function.MongoClient.saveData (/home/ubuntu/ds_queuesystem/MongoClient.js:34:21)
at /home/ubuntu/ds_queuesystem/DS_QueueSystem.js:84:18
at nextTask (/home/ubuntu/ds_queuesystem/node_modules/async/dist/async.js:6627:18)
at /home/ubuntu/ds_queuesystem/node_modules/async/dist/async.js:6621:17
at /home/ubuntu/ds_queuesystem/node_modules/async/dist/async.js:339:31
at /home/ubuntu/ds_queuesystem/node_modules/async/dist/async.js:840:20
at /home/ubuntu/ds_queuesystem/DS_QueueSystem.js:143:3
at null.<anonymous> (/home/ubuntu/ds_queuesystem/node_modules/csv-parse/lib/index.js:71:16)
at EventEmitter.emit (events.js:117:20)
at _stream_readable.js:920:16
at process._tickCallback (node.js:415:13)
Schema definition:
var schemaDefinition = "{SCHID: String, Priority: Number, Status: String, Json: Schema.Types.Mixed})";
schemaDefinition should be an Object, not a literal.
Try with:
var schemaDefinition = {
SCHID: String,
Priority: Number,
Status: String,
Json: Schema.Types.Mixed
};
Documentation: http://mongoosejs.com/docs/guide.html

bluebird + mongoose error: "Can't use $__ with Array."

I was trying to use bluebird + mongoose to query DevHiin instances for each Club respectively like the following code:
the data structure of DevHiin.clubs is:
, clubs : [{ type: Schema.Types.ObjectId, ref: 'Club' }]
and club_M is an instance of the Club schema:
User.findOne({"_id": req.user._id})
.populate('clubs', '-textIndex')
.exec(function (err, user) {
if (err) res.status(500).json(err);
if (user.clubs) {
var clubs_M = user.clubs;
for (c = 0; c < clubs_M.length; c++) {
var club_M = clubs_M[c];
if (club_M.lst > lstDate) {
serverData.clubs.push(club_M);
var ciinPromise = DevHiin.find({"clubs": {$elemMatch: club_M}, "ts": {"$gt": lastSyncTime}})
.populate('uId', '_id username', null, null) // get necessary user info for a hiin
.lean()
.sort("ts")
.limit(10)
.execAsync();
promises.push(ciinPromise);
}
}
Promise.all(promises).then(function (ciinArrays) {
serverData.ciinArrays = ciinArrays;
callback(ciinArrays);
}).catch(function (err) {
callback(err);
});
unfortunately, I got the following error info:
"Error: Can't use $__ with Array.
at SchemaArray.castForQuery (/Users/vince-fan/WorkSpaces/MEAN/V_Starter/node_modules/mongoose/lib/schema/array.js:188:13)
at SchemaArray.cast$elemMatch (/Users/vince-fan/WorkSpaces/MEAN/V_Starter/node_modules/mongoose/lib/schema/array.js:336:23)
at SchemaArray.castForQuery (/Users/vince-fan/WorkSpaces/MEAN/V_Starter/node_modules/mongoose/lib/schema/array.js:191:19)
at module.exports (/Users/vince-fan/WorkSpaces/MEAN/V_Starter/node_modules/mongoose/lib/cast.js:196:39)
at Query.cast (/Users/vince-fan/WorkSpaces/MEAN/V_Starter/node_modules/mongoose/lib/query.js:2350:10)
at Query.find (/Users/vince-fan/WorkSpaces/MEAN/V_Starter/node_modules/mongoose/lib/query.js:999:10)
at Query.exec (/Users/vince-fan/WorkSpaces/MEAN/V_Starter/node_modules/mongoose/lib/query.js:1984:17)
at Query.tryCatcher (/Users/vince-fan/WorkSpaces/MEAN/V_Starter/node_modules/bluebird/js/main/util.js:24:31)
at Query.ret [as execAsync] (eval at <anonymous> (/Users/vince-fan/WorkSpaces/MEAN/V_Starter/node_modules/bluebird/js/main/promisify.js:1:0), <anonymous>:12:23)
at EventEmitter.<anonymous> (/Users/vince-fan/WorkSpaces/MEAN/V_Starter/controllers/sync.js:189:18)
at EventEmitter.<anonymous> (/Users/vince-fan/WorkSpaces/MEAN/V_Starter/node_modules/mongoose/node_modules/mpromise/lib/promise.js:175:45)
at emitOne (events.js:77:13)
at EventEmitter.emit (events.js:169:7)
at Promise.safeEmit (/Users/vince-fan/WorkSpaces/MEAN/V_Starter/node_modules/mongoose/node_modules/mpromise/lib/promise.js:81:21)
at Promise.fulfill (/Users/vince-fan/WorkSpaces/MEAN/V_Starter/node_modules/mongoose/node_modules/mpromise/lib/promise.js:94:24)
at Promise.resolve (/Users/vince-fan/WorkSpaces/MEAN/V_Starter/node_modules/mongoose/lib/promise.js:113:23)
at /Users/vince-fan/WorkSpaces/MEAN/V_Starter/node_modules/mongoose/lib/query.js:1174:16
at /Users/vince-fan/WorkSpaces/MEAN/V_Starter/node_modules/mongoose/node_modules/kareem/index.js:109:16
at doNTCallback0 (node.js:408:9)
at process._tickCallback (node.js:337:13)"
is this an bluebird promise error, or an mongoose error? how can I fix it?
From the code it looks like you are trying to query using $elemMatch on an array value specified as the query criteria expression. I believe you need to use the $in instead, this selects the documents where the value of the clubs field equals any value in the specified array, which is stored by the variable club_M in your case. Thus your query should look like this:
var ciinPromise = DevHiin.find({"clubs": {"$in": [club_M._id]}, "ts": {"$gt": lastSyncTime}})
for querying field holds an array, simple treat it as normal field query.
My fixed code:
var ciinPromise = DevHiin.find({"clubs": club_M._id, "ts": {"$gt": lastSyncTime}})

Sequelize Migration Error

I'm using Sequelize 2.0.0-rc3 and there's an error I'm encountering; it seems like I'm writing the migration correctly but I'm getting an error trying to run it. I'm using Postgresql on the backend. Everything seems to be working fine; this is a new, isolated issue. The Document table and id column exists (created it in a previous migration, but discovered it's not auto-incrementing id's; so tried creating this migration to add auto-incrementing).
var p = require('bluebird');
module.exports = {
up: function (migration, DataTypes, done) {
var promises = [];
promises.push(
migration.changeColumn(
'Document',
'id',
{
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
allowNull: false
}
));
p.all(promises).then(done.bind(null, null)).catch(function (err) {
console.error('Migration Failed: ', err);
done(err);
});
},
down: function (migration, DataTypes, done) {
done();
}
};
Possibly unhandled TypeError: Cannot call method 'push' of undefined
at Object.module.exports.QueryGenerator.dataTypeMapping (/Users/csimpson/code/temp-cause-server/node_modules/sequelize/lib/dialects/postgres/query-generator.js:848:32)
at Object.module.exports.QueryGenerator.pgDataTypeMapping (/Users/csimpson/code/temp-cause-server/node_modules/sequelize/lib/dialects/postgres/query-generator.js:843:19)
at Object.module.exports.QueryGenerator.changeColumnQuery (/Users/csimpson/code/temp-cause-server/node_modules/sequelize/lib/dialects/postgres/query-generator.js:250:31)
at module.exports.QueryInterface.changeColumn (/Users/csimpson/code/temp-cause-server/node_modules/sequelize/lib/query-interface.js:345:37)
at module.exports.Migration.(anonymous function) [as changeColumn] (/Users/csimpson/code/temp-cause-server/node_modules/sequelize/lib/migration.js:26:50)
at /Users/csimpson/code/temp-cause-server/database/migrations/20141216000001-alter-id-increment.js:8:41
at tryCatch1 (/Users/csimpson/code/temp-cause-server/node_modules/sequelize/node_modules/bluebird/js/main/util.js:45:21)
at Promise$_callHandler [as _callHandler] (/Users/csimpson/code/temp-cause-server/node_modules/sequelize/node_modules/bluebird/js/main/promise.js:660:13)
at Promise$_settlePromiseFromHandler [as _settlePromiseFromHandler] (/Users/csimpson/code/temp-cause-server/node_modules/sequelize/node_modules/bluebird/js/main/promise.js:675:18)
at Promise$_settlePromiseAt (/Users/csimpson/code/temp-cause-server/node_modules/sequelize/node_modules/bluebird/js/main/promise.js:845:14)
I ran into the Possibly unhandled TypeError: Cannot call method 'push' of undefined error as well. I was also trying to add an id field to an existing table, one I had created in the previous migration.
My fix had two parts:
1) Add unique: true to the id column.
2) Undo the previous migration (where I created the table that I want to add an id column to), and then run both migrations at once.
Until I did both of these, my migration attempts failed.

Mongoose TypeError: Cannot use 'in' operator to search for '_id' in [object Object]

I am new to mongodb and for the past couple days I have been trying to get my entries into my mongolab instance but have not had any luck. It seems when I execute the save call I get an error stating:
TypeError: Cannot use 'in' operator to search for '_id' in [object Object]
The [object Object] they are referring to is my Color schema. I havent been able to find an answer yet and thought I would post here to work in parallel while I research more. I have pasted a snipit of what I am using in hopes that it is just something stupid I am doing. TIA!
mongoose.connect(config.db.mongodb);
var Schema = mongoose.Schema,
ObjectId = Schema.ObjectId;
var Color = new Schema({
hex : {type:String, required: true, trim: true}
,perc : {type:String, required: true, trim: true}
});
var Img = new Schema({
path : {type:String, required: true, trim: true}
,color : [Color]
});
var imgModel = mongoose.model('Img', Img);
exports.addImage = function(req,res){
//First check to see if we already have the image stored
imgModel.findOne({path: req.query.path}, function(error, image){
if(error){
console.log("Error");
res.json(error);
}
else if(image === null){
//There is no image so just store the info
var image_data = {
path: req.query.path,
color: req.query.color
};
var img = new imgModel(image_data);
img.save(function(error, data){
//*** This error block below is where I am
// entering and the message is displayed
if(error){
console.log("Oh noo: ",error);
res.json(error);
}
else{
console.log("Saving: ",data);
res.json(data);
}
});
} else{
//The path is already here
//res.json("Image already in db");
console.log("Image already in db");
}
});
};
So it was due to the way my color object was being unescaped when the request was being handled. Upon entering it was seeing the object but the nested values were not valid and therfore was throwing off the write tot eh db as it was expecting Strings. I ended up doing a POST instead and passing the json object in the data param and then reading it back out through the body and it works as expected and has automatically created the db as desired. Thanks Noah for the response!

Resources