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.
Related
I'm trying to implement an autoicremental user_key field. Looking on this site I came across two questions relevant for my problem but I don't clearly understand what I should do. This is the main one
I have two Mongoose models, this is my ProductsCounterModel.js
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
var Counter = new Schema({
_id: {type: String, required: true},
sequence_value: {type: Number, default: 0}
});
module.exports = mongoose.model('products_counter', Counter);
and this is the Mongoose model where I try to implement the auto-increment field:
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
var products_counter = require('./ProductsCounterModel.js');
var HistoricalProduct = new Schema({
product_key: { type: Number },
class: { type: String },
brand: { type: String },
model: { type: String },
description: { type: String }
});
HistoricalProduct.pre("save", function (next) {
console.log("first console log:",products_counter);
var doc = this;
products_counter.findOneAndUpdate(
{ "_id": "product_key" },
{ "$inc": { "sequence_value": 1 } },
function(error, products_counter) {
if(error) return next(error);
console.log("second console log",products_counter);
doc.product_key = products_counter.sequence_value;
next();
});
});
module.exports = mongoose.model('HistoricalProduct', HistoricalProduct);
Following the steps provided in the above SO answer I created the collection products_counter and inserted one document.
The thing is that I'm getting this error when I try to insert a new product:
"TypeError: Cannot read property 'sequence_value' of null"
This are the outputs of the above console logs.
first console log output:
function model (doc, fields, skipId) {
if (!(this instanceof model))
return new model(doc, fields, skipId);
Model.call(this, doc, fields, skipId);
}
second console log:
Null
can you see what I'm doing wrong?
You can run following line in your middleware:
console.log(products_counter.collection.collectionName);
that line will print products_counters while you expect that your code will hit products_counter. According to the docs:
Mongoose by default produces a collection name by passing the model name to the utils.toCollectionName method. This method pluralizes the name. Set this option if you need a different name for your collection.
So you should either rename collection products_counter to products_counters or explicitly configure collection name in your schema definition:
var Counter = new Schema({
_id: {type: String, required: true},
sequence_value: {type: Number, default: 0}
}, { collection: "products_counter" });
I have seen this question:
mongoose TypeError: Schema is not a constructor
However I still cannot using Models with Mongoose.
When I am trying this:
const mongoose = require('mongoose').connect(`mongodb://${process.env.DB_USER}:${process.env.DB_PASSWORD}#localhost:27017/${process.env.DB_NAME}`, {useNewUrlParser: true});
const Schema = mongoose.Schema;
var blogSchema = new Schema({
title: String,
author: String,
body: String,
comments: [{ body: String, date: Date }],
date: { type: Date, default: Date.now },
hidden: Boolean,
meta: {
votes: Number,
favs: Number
}
});
var Blog = mongoose.model('Blog', blogSchema);
I receive the following error:
TypeError: Schema is not a constructor
at module.exports (/Users/razbuchnik/Projects/taxi4you/server/resources/permissions/api/v1-update.js:30:20)
at Layer.handle [as handle_request] (/Users/razbuchnik/Projects/taxi4you/server/node_modules/express/lib/router/layer.js:95:5)
at next (/Users/razbuchnik/Projects/taxi4you/server/node_modules/express/lib/router/route.js:137:13)
at /Users/razbuchnik/Projects/taxi4you/server/app/middlewares/permission.js:27:7
at /Users/razbuchnik/Projects/taxi4you/server/node_modules/mongojs/lib/collection.js:50:5
at runInAsyncScope (/Users/razbuchnik/Projects/taxi4you/server/node_modules/mongojs/lib/cursor.js:198:5)
at /Users/razbuchnik/Projects/taxi4you/server/node_modules/mongojs/lib/cursor.js:205:5
at handleCallback (/Users/razbuchnik/Projects/taxi4you/server/node_modules/mongojs/node_modules/mongodb/lib/utils.js:120:56)
at /Users/razbuchnik/Projects/taxi4you/server/node_modules/mongojs/node_modules/mongodb/lib/cursor.js:683:5
at handleCallback (/Users/razbuchnik/Projects/taxi4you/server/node_modules/mongojs/node_modules/mongodb-core/lib/cursor.js:171:5)
at nextFunction (/Users/razbuchnik/Projects/taxi4you/server/node_modules/mongojs/node_modules/mongodb-core/lib/cursor.js:691:5)
at /Users/razbuchnik/Projects/taxi4you/server/node_modules/mongojs/node_modules/mongodb-core/lib/cursor.js:602:7
at queryCallback (/Users/razbuchnik/Projects/taxi4you/server/node_modules/mongojs/node_modules/mongodb-core/lib/cursor.js:232:18)
at /Users/razbuchnik/Projects/taxi4you/server/node_modules/mongojs/node_modules/mongodb-core/lib/connection/pool.js:469:18
at _combinedTickCallback (internal/process/next_tick.js:131:7)
at process._tickCallback (internal/process/next_tick.js:180:9)
Note: this is a copy pase from official Mongoose site and GitHub repo.
The problem is that mongoose is not Mongoose object but connect promise.
It should be:
const mongoose = require('mongoose')
const Schema = mongoose.Schema;
mongoose.connect(`mongodb://${process.env.DB_USER}:${process.env.DB_PASSWORD}#localhost:27017/${process.env.DB_NAME}`, {useNewUrlParser: true});
Notice that mongoose.connect may be suitable not for model but parent module because there could be multiple model modules.
If anyone else has the problem and is still unable to figure it out, maybe in your model file instead of module.exports= maybe you have module.export=
This might not help op, but was something that caused me 30 minutes of pain, hence pasting it here.
The error is because your const mongoose has the instance of mongoose.connect and not mongoose.
Try this:
const mongoose = require('mongoose');
const connect = mongoose.connect(`mongodb://${process.env.DB_USER}:${process.env.DB_PASSWORD}#localhost:27017/${process.env.DB_NAME}`, {useNewUrlParser: true});
const Schema = mongoose.Schema;
var blogSchema = new Schema({
title: String,
author: String,
body: String,
comments: [{ body: String, date: Date }],
date: { type: Date, default: Date.now },
hidden: Boolean,
meta: {
votes: Number,
favs: Number
}
});
var Blog = mongoose.model('Blog', blogSchema);
Hope, this helps you.
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.
I am encountering a problem where my Mongoose pre.save() hook is firing, but the attribute does not get saved to the database. I have been searching for a long time without finding an answer.I found this thread, and the behaviour I am experiencing is very similiar, but OP's problem is related to the context of this, whereas I seem to have a different problem.
Here is my models.js:
'use strict';
const mongoose = require("mongoose");
const slugify = require("slugify");
let Schema = mongoose.Schema;
let BlogPostSchema = new Schema({
title: {
type: String,
required: true
},
createdAt: {type: Date, default: Date.now},
updatedAt: {type: Date, default: Date.now},
author: String,
post: {
type: String,
required: true
}
});
BlogPostSchema.pre('save', function(next) {
this.slug = slugify(this.title);
console.log(this.slug);
next();
});
// Passed to templates to generate url with slug.
BlogPostSchema.virtual("url").get(function() {
console.log(this.slug);
console.log(this.id);
return this.slug + "/" + this.id;
});
BlogPostSchema.set("toObject", {getters: true});
let BlogPost = mongoose.model("BlogPost", BlogPostSchema);
module.exports.BlogPost = BlogPost;
And here is the relevant lines in the router file index.js:
const express = require('express');
const router = express.Router();
const BlogPost = require("../models").BlogPost;
// Route for accepting new blog post
router.post("/new-blog-post", (req, res, next) => {
let blogPost = new BlogPost(req.body);
blogPost.save((err, blogPost) => {
if(err) return next(err);
res.status(201);
res.json(blogPost);
});
});
I am able to save the blog post to the database, and my console.log's correctly prints out the slug to the console. However, the this.slug in the pre-save hook does not get persisted in the database.
Can anybody see what the problem is here? Thank you so much in advance.
Mongoose will act according to the schema you defined.
Currently, your schema does not contain s filed named slug.
You should add a slug field to your schema.
Changing your current schema to something like this should work:
let BlogPostSchema = new Schema({
slug: String,
title: {
type: String,
required: true
},
createdAt: {type: Date, default: Date.now},
updatedAt: {type: Date, default: Date.now},
author: String,
post: {
type: String,
required: true
}
});
I'm having trouble trying to add instance methods to my schemas.
Here is an example:
var mongoose = require('mongoose');
var bcrypt = require('bcryptjs');
var schema = new mongoose.Schema ({
first_name: {type: String, required: true, trim: true},
last_name: {type: String, required: true, trim: true},
email: {type: String, required: true, unique: true, dropDups: true, trim:true},
hash: {type: String, required: true}
});
schema.methods = {
encrypt: function(pwd) {
if (!pwd) return '';
else return bcrypt.hashSync(pwd, bcrypt.genSaltSync(10));
},
test: function(logentry) {
console.log(this.email + ': ' + logentry);
}
};
mongoose.model('Users', schema);
And then in my code elsewhere I try to call one of the methods:
var mongoose = require('mongoose');
var Users = mongoose.model('Users');
function testFunction(email) {
Users.find({email:email}, function(error, user) {
user.test('Trying to make mongoose instance methods work.');
});
}
testFunction('goofy#goober.com');
And then I get the following error (stacktrace omitted):
user.test('Trying to make mongoose instance methods work.');
^
TypeError: undefined is not a function
I cannot for the life of me figure this out..
I am using mongoose 3.8. I know I'm doing something wrong, but I need another, much smarter and experienced pair of eyes to help me find it.
I've tried defining the methods like this too:
schema.methods.encrypt = function(pwd) {...};
schema.methods.test = function(logentry) {...};
But it doesn't seem to matter.
There was only one previous post like this that I could find on stack overflow and they resolved their error by making sure that their methods were defined before they called mongoose.model('name', schema). I've got them defined before, so I don't think it's the same problem. Any help would be much appreciated.
The problem is that Users.find gives you an array.
So, either:
Users.find({ email: email }, function (e, users) {
users[0].test('foo bar whatever');
});
or:
Users.findOne({ email: email }, function (e, user) {
user.test('foo bar whatever');
});