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

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

Related

How to print the full stacktrace for mongoose validation errors

Is there a way to have the stacktrace show the line in code which called save?
I was testing my validation logic and noticed that Mongoose doesn't print a stacktrace to where I call save(). While the validation does say what went wrong, it is not saying where this is located.
const mySchema = new mongoose.Schema({
name: {
type: String,
required: true,
},
accessToken: {
type: String,
required: true,
},
})
mySchema.statics.createOrUpdate = async function(name, accessToken) {
const animal = await this.findOne({ name })
if (!animal) {
animal = new Animal({ name }) // accessToken is missing and required
}
await animal.save() // expected stacktrace error here
}
ValidationError: Animal validation failed: accessToken: Path `accessToken` is required.
at model.Document.invalidate (/Users/michael/repos/MyApp/node_modules/mongoose/lib/document.js:2622:32)
at /Users/michael/repos/MyApp/node_modules/mongoose/lib/document.js:2442:17
at /Users/michael/repos/MyApp/node_modules/mongoose/lib/schematype.js:1225:9
at processTicksAndRejections (internal/process/task_queues.js:79:11)
If I rethrow the error, I can get a more descriptive stacktrace. But I rather not need to do this:
...
await animal.save().catch((e) => { throw Error(e) })
Error: ValidationError: accessToken: Path `accessToken` is required.
at /Users/michael/repos/MyApp/models/Animal.js:19:42
at processTicksAndRejections (internal/process/task_queues.js:97:5)

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.

Node server crashes when trying to save mongoose document with unique index

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(){..});

"Object {} has no method 'cast' error" when trying to add item to mongoose array

I'm trying to create a todo app using node.js, mongoose and backbone for learning purposes.
Up till now I defined these models:
var TaskSchema = new mongoose.Schema({
title: { type:String },
content: { type:String } ,
created: {type:Date, 'default':Date.now},
due: {type:Date},
accountId: {type:mongoose.Schema.ObjectId}
});
var Task = mongoose.model('Task',TaskSchema);
var AccountSchema = new mongoose.Schema({
email: { type:String, unique: true},
password: { type:String } ,
name: { first: {type:String},
last: { type:String } },
birthday: {
day: {type:Number, min:1, max:31, required:false},
month: {type:Number, min:1, max:12, required:false},
year: {type:Number}
},
photoUrl: {type:String},
biography:{type:String},
tasks:[Task]
});
var Account = mongoose.model('Account',AccountSchema);
In addition, I also have the following method for adding a task:
var enter_new_task = function(options,callback){
var title = options.title;
var content = options.content;
var due = options.due;
var account = options.account;
var task = new Task({
title: title,
content: content,
due: due,
accountId: account._id
});
account.tasks.push(task);
account.save(function(err) {
if ( err ) {
console.log("Error while saving task: " + err);
}else{
callback();
}
})
}
But when I indeed add a task, I get an error that says:
"Object {} has no method 'cast'"
With the following stack trace:
at Array.MongooseArray._cast (/home/lior/workspace/todo_express/node_modules/mongoose/lib/types/array.js:107:30)
at Object.map (native)
at Array.MongooseArray.push (/home/lior/workspace/todo_express/node_modules/mongoose/lib/types/array.js:261:23)
at Object.enter_new_task (/home/lior/workspace/todo_express/models/Account.js:107:17)
at /home/lior/workspace/todo_express/app.js:104:18
at Promise.<anonymous> (/home/lior/workspace/todo_express/models/Account.js:41:4)
at Promise.<anonymous> (/home/lior/workspace/todo_express/node_modules/mongoose/node_modules/mpromise/lib/promise.js:162:8)
at Promise.EventEmitter.emit (events.js:95:17)
at Promise.emit (/home/lior/workspace/todo_express/node_modules/mongoose/node_modules/mpromise/lib/promise.js:79:38)
at Promise.fulfill (/home/lior/workspace/todo_express/node_modules/mongoose/node_modules/mpromise/lib/promise.js:92:20)
9
It seems that the problem is with the line that the new task to the tasks array.
Couldn't find anything on google or stack so I wonder, does anyone have an idea about what went wrong?
Thanks!
The error is in the AccountSchema definition. A subdocument type should be a schema, not a model.
var AccountSchema = new mongoose.Schema({
//...
tasks:[TaskSchema]
});
Alternatively, if you don't have direct access to your schema, and only have access to the model, you can access the model's schema with dot notation like this:
var AccountSchema = new mongoose.Schema({
//...
tasks:[Task.schema]
});
This is helpful if you've defined your schema in another file and are using something like this:
module.exports = mongoose.model('Task', TaskSchema);

NodeJS - Mongoose (Object has no method "id")

When I try this code in my Application:
app/models/Post.coffee
mongoose = require "mongoose"
CommentModel = require "./Comment"
Comment = CommentModel.Schema
Schema = mongoose.Schema
Post = new Schema {
title: String,
slug: {type: String, index: { unique: true, dropDubs: true }},
content: String,
author: String,
tags: [String],
comments: [Comment],
created: { type: Date, default: Date.now }
}
Post.statics.findBySlug = (slug, cb) ->
this.model("Post").findOne({ slug: slug }, cb)
PostModel = mongoose.model "Post", Post
module.exports = PostModel
app/models/Comment.coffee
mongoose = require("mongoose")
Schema = mongoose.Schema
Comment = new Schema {
author: String,
content: String,
approved: Boolean,
created: { type: Date, default: Date.now }
}
CommentModel = mongoose.model "Comment", Comment
module.exports = CommentModel
app/controllers/PostsController.coffee (Just one method)
commentDestroy: (req, res, next) ->
Post.findBySlug req.params.slug, (err, doc) ->
if (err)
return next err
if doc == null
res.send 404
return
doc.comments.id(req.params.comment).remove()
doc.save (err) ->
if err
next err
res.json doc
It ends with error:
TypeError: Object [object Object],[object Object],[object Object],[object Object],[object Object] has no method 'id'
at Promise.PostsController.commentDestroy (/home/r41ngoloss/Projects/www/my-express/app/controllers/PostsController.js:88:22)
at Promise.addBack (/home/r41ngoloss/Projects/www/my-express/node_modules/mongoose/lib/promise.js:128:8)
at Promise.EventEmitter.emit (events.js:96:17)
at Promise.emit (/home/r41ngoloss/Projects/www/my-express/node_modules/mongoose/lib/promise.js:66:38)
at Promise.complete (/home/r41ngoloss/Projects/www/my-express/node_modules/mongoose/lib/promise.js:77:20)
at Query.findOne (/home/r41ngoloss/Projects/www/my-express/node_modules/mongoose/lib/query.js:1533:15)
at model.Document.init (/home/r41ngoloss/Projects/www/my-express/node_modules/mongoose/lib/document.js:229:11)
at model.init (/home/r41ngoloss/Projects/www/my-express/node_modules/mongoose/lib/model.js:192:36)
at Query.findOne (/home/r41ngoloss/Projects/www/my-express/node_modules/mongoose/lib/query.js:1531:12)
at exports.tick (/home/r41ngoloss/Projects/www/my-express/node_modules/mongoose/lib/utils.js:408:16)
I already tried to find solution for my problem, but i found just this and I think, that I have schemas in right order (By require).
Thanks for every answer.
The reason that your are getting that error is that you are not getting the Comment schema correctly in the Post.coffee file. When I do what you did, the Comment variable is undefined. Modify the top of your Post.coffee file to:
mongoose = require "mongoose"
Comment = mongoose.model('Comment').schema
Schema = mongoose.Schema
Now the Comment variable is the schema of the Comment model.

Resources