I am interested in writing a mongoose plug in to make all fields required. I know there are other ways to do this, but I like the idea of writing my own plug in.
From docs http://mongoosejs.com/docs/plugins:
// game-schema.js
var lastMod = require('./lastMod');
var Game = new Schema({ ... });
Game.plugin(lastMod, { index: true });
but when I create a model from my schema and look at the properties, I don't see a plugin() method:
var mongoose = require('mongoose');
var CpuSchema = require("../schemas/cpu");
var Cpu = mongoose.model('Cpu', CpuSchema);
console.log(Cpu);
module.exports = Cpu;
one#demo ~/cloudimageshare-monitoring/project $ node /home/one/cloudimageshare-monitoring/project/app/data/models/cpu.js
{ [Function: model]
base:
{ connections: [ [Object] ],
plugins: [],
models: { Cpu: [Circular] },
modelSchemas: { Cpu: [Object] },
options: { pluralization: true } },
modelName: 'Cpu',
model: [Function: model],
db:
{ base:
{ connections: [Object],
plugins: [],
models: [Object],
modelSchemas: [Object],
options: [Object] },
collections: { cpus: [Object] },
models: {},
replica: false,
hosts: null,
host: null,
port: null,
user: null,
pass: null,
name: null,
options: null,
otherDbs: [],
_readyState: 0,
_closeCalled: false,
_hasOpened: false,
_listening: false },
discriminators: undefined,
schema:
{ paths:
{ timeStamp: [Object],
avaiable: [Object],
status: [Object],
metrics: [Object],
_id: [Object],
__v: [Object] },
subpaths: {},
virtuals: { id: [Object] },
nested: {},
inherits: {},
callQueue: [],
_indexes: [],
methods: {},
statics: {},
tree:
{ timeStamp: [Object],
avaiable: [Function: Boolean],
status: [Function: String],
metrics: [Object],
_id: [Object],
id: [Object],
__v: [Function: Number] },
_requiredpaths: undefined,
discriminatorMapping: undefined,
_indexedpaths: undefined,
options:
{ id: true,
noVirtualId: false,
_id: true,
noId: false,
read: null,
shardKey: null,
autoIndex: true,
minimize: true,
discriminatorKey: '__t',
versionKey: '__v',
capped: false,
bufferCommands: true,
strict: true,
pluralization: true },
_events: {} },
options: undefined,
collection:
{ collection: null,
opts: { bufferCommands: true, capped: false },
name: 'cpus',
conn:
{ base: [Object],
collections: [Object],
models: {},
replica: false,
hosts: null,
host: null,
port: null,
user: null,
pass: null,
name: null,
options: null,
otherDbs: [],
_readyState: 0,
_closeCalled: false,
_hasOpened: false,
_listening: false },
queue: [ [Object] ],
buffer: true } }
Here on the model, I don't see a plugin() method.
The plugin method is defined on the Schema class and you can see it on your CpuSchema object.
On your Cpu model you can get it by calling
console.log(Cpu.schema.plugin)
From the mongoose source code on GitHub:
/**
* Registers a plugin for this schema.
*
* #param {Function} plugin callback
* #param {Object} opts
* #see plugins
* #api public
*/
Schema.prototype.plugin = function (fn, opts) {
fn(this, opts);
return this;
};
When you pass your plugin function to it it simply executes the function and passes the schema reference into it.
Related
when hitting a get route, I get the data I am expecting but it looks like my route is hit TWICE: once with data, and another time with no info supplied.
if I navigate to a URL: https://www.something.com/events/XYZ then I get all the data and the page is populated properly. The page never seems to finish loading unless I click on the "X" in the browser.
app.get("/events/:id", function(req, res){
Event.findById(req.params.id, function (err, foundEvent){
if(err){
console.log("beginning error");
console.log(err);
console.log("found this event: " + foundEvent);
console.log("ending error");
}else {
console.log("now entering normal loop");
console.log(foundEvent);
res.render("showevent", {event: foundEvent});
}
})
});
When I type in a URL (copy/paste), I get the following (lengthy, sorry, not sure which part may be relevant) console.log:
now entering normal loop
{ _id: 5cf30944e75f2679f77287a2,
name: 'Memorial Day 2019',
date: 2019-06-01T23:24:52.063Z,
story: 'Memorial Day parade and Ceremony',
posts: [ { link: [Array], image: [], _id: 5cf30944e75f2679f77287a3 } ],
__v: 0 }
beginning error
{ CastError: Cast to ObjectId failed for value "main.js" at path "_id" for model "Event"
at new CastError (/home/scott/cchistory/cchistory/node_modules/mongoose/lib/error/cast.js:29:11)
at ObjectId.cast (/home/scott/cchistory/cchistory/node_modules/mongoose/lib/schema/objectid.js:242:11)
at ObjectId.SchemaType.applySetters (/home/scott/cchistory/cchistory/node_modules/mongoose/lib/schematype.js:892:12)
at ObjectId.SchemaType._castForQuery (/home/scott/cchistory/cchistory/node_modules/mongoose/lib/schematype.js:1304:15)
at ObjectId.SchemaType.castForQuery (/home/scott/cchistory/cchistory/node_modules/mongoose/lib/schematype.js:1294:15)
at ObjectId.SchemaType.castForQueryWrapper (/home/scott/cchistory/cchistory/node_modules/mongoose/lib/schematype.js:1273:15)
at cast (/home/scott/cchistory/cchistory/node_modules/mongoose/lib/cast.js:307:32)
at model.Query.Query.cast (/home/scott/cchistory/cchistory/node_modules/mongoose/lib/query.js:4529:12)
at model.Query.Query._castConditions (/home/scott/cchistory/cchistory/node_modules/mongoose/lib/query.js:1762:10)
at model.Query.<anonymous> (/home/scott/cchistory/cchistory/node_modules/mongoose/lib/query.js:2015:8)
at model.Query._wrappedThunk [as _findOne] (/home/scott/cchistory/cchistory/node_modules/mongoose/lib/helpers/query/wrapThunk.js:16:8)
at process.nextTick (/home/scott/cchistory/cchistory/node_modules/kareem/index.js:369:33)
at _combinedTickCallback (internal/process/next_tick.js:131:7)
at process._tickCallback (internal/process/next_tick.js:180:9)
message: 'Cast to ObjectId failed for value "main.js" at path "_id" for model "Event"',
name: 'CastError',
stringValue: '"main.js"',
kind: 'ObjectId',
value: 'main.js',
path: '_id',
reason: undefined,
model:
{ [Function: model]
hooks: Kareem { _pres: [Object], _posts: [Object] },
base:
Mongoose {
connections: [Array],
models: [Object],
modelSchemas: [Object],
options: [Object],
_pluralize: [Function: pluralize],
Schema: [Object],
model: [Function],
plugins: [Array] },
modelName: 'Event',
model: [Function: model],
db:
NativeConnection {
base: [Object],
collections: [Object],
models: [Object],
config: [Object],
replica: false,
options: null,
otherDbs: [],
relatedDbs: {},
states: [Object],
_readyState: 1,
_closeCalled: false,
_hasOpened: true,
plugins: [],
'$internalEmitter': [Object],
_listening: false,
_connectionOptions: [Object],
name: 'historydb',
host: 'localhost',
port: 27017,
user: undefined,
pass: undefined,
client: [Object],
'$initialConnection': [Object],
db: [Object] },
discriminators: undefined,
events:
EventEmitter {
domain: null,
_events: {},
_eventsCount: 0,
_maxListeners: undefined },
'$appliedMethods': true,
'$appliedHooks': true,
_middleware: Kareem { _pres: [Object], _posts: [Object] },
'$__insertMany': [Function],
schema:
Schema {
obj: [Object],
paths: [Object],
aliases: {},
subpaths: {},
virtuals: [Object],
singleNestedPaths: {},
nested: {},
inherits: {},
callQueue: [],
_indexes: [],
methods: {},
methodOptions: {},
statics: {},
tree: [Object],
query: {},
childSchemas: [Array],
plugins: [Array],
'$id': 6,
s: [Object],
_userProvidedOptions: {},
options: [Object],
'$globalPluginsApplied': true,
_requiredpaths: [] },
collection:
NativeCollection {
collection: [Object],
Promise: [Function: Promise],
opts: [Object],
name: 'events',
collectionName: 'events',
conn: [Object],
queue: [],
buffer: false,
emitter: [Object] },
Query: { [Function] base: [Object] },
'$init': Promise { [Circular] },
'$caught': true,
[Symbol(mongoose#Model)]: true } }
found this event: undefined
ending error
The "double whammy" was caused by a search bar that was on the page. With not info entered, it would hit the route with no info and cause the error.
I am moving the search function to a dedicated page for simplicity.
Thanks for the help folks!
i have used a middleware called checktoken in every routes except login route in my code . when i hit login url it logged me in where there is to token checked. but now if i wish to go to any route after logging in it restricts me inside checkToken middleware.i have used jsonwebtoken module to generate token and verify it.but my code failed to find users.here is my checktoken middle ware code
if (token) {
try {
var decoded = jsonwebtoken.verify(token, jwt_key);
req.user = decoded.user;///
console.log(req.user._id);// i get id here and from this id i can find user in database
UserSchema.findOne({
_id: req.user._id
})///this query failed finding result
.exec(function(err, result) {
if (err) {
console.log(err);//error gets output in the console.
res.status(500);
return res.json({
result: err
});
}
if (result) {
return next();
} else {
res.status(400);
return res.json({
message: "The user does not exists"
});
}
});
} catch (err) {
res.status(403);
res.json({
message: "Invalid Token"
});
}
} else {
res.status(401);
res.json({
message: "No token provided"
});
}
the error message i get in console is
{ [CastError: Cast to ObjectId failed for value "5875d76e1df97635623061c5" at path "_id" for model "User"]
message: 'Cast to ObjectId failed for value "5875d76e1df97635623061c5" at path "_id" for model "User"',
name: 'CastError',
stringValue: '"5875d76e1df97635623061c5"',
kind: 'ObjectId',
value: '5875d76e1df97635623061c5',
path: '_id',
reason: undefined,
model:
{ [Function: model]
hooks: Kareem { _pres: {}, _posts: {} },
base:
Mongoose {
connections: [Object],
plugins: [],
models: [Object],
modelSchemas: [Object],
options: [Object] },
modelName: 'User',
model: [Function: model],
db:
NativeConnection {
base: [Object],
collections: [Object],
models: [Object],
config: [Object],
replica: false,
hosts: null,
host: 'localhost',
port: 27017,
user: undefined,
pass: undefined,
name: 'myschoolbus_demo',
options: [Object],
otherDbs: [],
_readyState: 1,
_closeCalled: false,
_hasOpened: true,
_listening: false,
db: [Object] },
discriminators: undefined,
schema:
Schema {
obj: [Object],
paths: [Object],
subpaths: {},
virtuals: [Object],
singleNestedPaths: {},
nested: [Object],
inherits: {},
callQueue: [Object],
_indexes: [],
methods: [Object],
statics: {},
tree: [Object],
_requiredpaths: undefined,
discriminatorMapping: undefined,
_indexedpaths: undefined,
query: {},
childSchemas: [],
s: [Object],
options: [Object],
'$globalPluginsApplied': true },
collection:
NativeCollection {
collection: [Object],
opts: [Object],
name: 'users',
collectionName: 'users',
conn: [Object],
queue: [],
buffer: false,
emitter: [Object] },
Query: { [Function] base: [Object] },
'$__insertMany': [Function],
insertMany: [Function] } }
i cannot figure out where i am wrong. any suggestions are highly appreciated.
Strip quotes from your id. Your error says:
stringValue: '"5875d76e1df97635623061c5"',
See the " at start and end? It's part of the string. I don't know if your middleware, or frontend or whoever puts it, so either strip it yourself or pass it before.
Try this:
UserSchema.findOne({
_id: req.user._id.replace(/"/g, '')
})
I am trying to deploy my Expressjs application into lambda, but i am getting below error. Please try to me to resolve this error.
lambda response:
{
"statusCode": 502,
"body": "",
"headers": {}
}
lambda log (it contains console of mongo connection and error)
NativeConnection {
base:
Mongoose {
connections: [ [Circular] ],
plugins: [],
models: { Student: [Object] },
modelSchemas: { Student: [Object] },
options: { pluralization: true } },
collections:
{ student:
NativeCollection {
collection: [Object],
opts: [Object],
name: 'student',
collectionName: 'student',
conn: [Circular],
queue: [],
buffer: false,
emitter: [Object] } },
models:
{ Student:
{ [Function: model]
hooks: [Object],
base: [Object],
modelName: 'Student',
model: [Function: model],
db: [Circular],
discriminators: undefined,
schema: [Object],
collection: [Object],
Query: [Object],
'$__insertMany': [Function],
insertMany: [Function] } },
config: { autoIndex: true },
replica: false,
hosts: null,
host: '1.0.0.0.0',
port: 3000,
user: undefined,
pass: undefined,
name: 'sudentdb',
options:
{ mongos: {},
db: { safe: true, forceServerObjectId: false },
auth: {},
server: { socketOptions: {}, auto_reconnect: true },
replset: { socketOptions: {} } },
otherDbs: [],
_readyState: 1,
_closeCalled: false,
_hasOpened: true,
_listening: false,
db:
EventEmitter {
domain: null,
_events:
{ close: [Function],
error: [Function],
reconnect: [Function],
timeout: [Function],
open: [Function],
parseError: [Function] },
_eventsCount: 6,
_maxListeners: undefined,
s:
{ databaseName: 'studentdb',
dbCache: {},
children: [],
topology: [Object],
options: [Object],
logger: [Object],
bson: {},
authSource: undefined,
readPreference: undefined,
bufferMaxEntries: -1,
parentDb: null,
pkFactory: undefined,
nativeParser: undefined,
promiseLibrary: [Function: Promise],
noListener: false,
readConcern: undefined },
serverConfig: [Getter],
bufferMaxEntries: [Getter],
databaseName: [Getter],
_listening: true },
_events:
{ connected: [Function],
error: [Function],
disconnected: [Function] },
_eventsCount: 3 }
{ [Error: socket hang up] code: 'ECONNRESET' }
student.model.js
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
var studentSchema = new Schema({
name: String,
rollnumber: Number,
},{collection:"student"});
module.exports = mongoose.model('Student', studentSchema);
api/student(REST API - GET method)
exports.index = function(req, res) {
console.log(mongoose.connection)
Student.findOne({},function(err,doc){
if(err){
return res.json("error found");
}else{
return res.json(doc);
}
});
};
lambda.js
'use strict'
const awsServerlessExpress = require('aws-serverless-express');
const app = require('./bin/www');
const server = awsServerlessExpress.createServer(app);
exports.handler = (event,context)=>{
console.log("EVENT: " + JSON.stringify(event));
awsServerlessExpress.proxy(server,event,context);
}
Just cannot get my head around this after 10 hours of trying:
if I
users.findById(req.body.user_id,function(e,doc){});
and console.log the doc returned, all looks good:
{ _id: 54dcad6de4b01007caacb0cd,
username: 'realizertest',
password: '******************************',
first_name: 'Realizer',
second_name: 'Test',
display_name: 'Realizer Test',
email: 'system#realizerlabs.com' }
However, when trying to access the included fields, e.g. by:
user = users.findById(req.body.user_id,function(e,doc){});
var user_email = user.email;
I just get undefined. The user object looks like this:
{ col:
{ manager:
{ driver: [Object],
helper: [Object],
collections: [Object],
options: [Object],
_events: {} },
driver:
{ _construct_args: [],
_native: [Object],
_emitter: [Object],
_state: 2,
_connect_args: [Object] },
helper: { toObjectID: [Function], id: [Ob
name: 'users',
col:
{ _construct_args: [],
_native: [Object],
_emitter: [Object],
_state: 2,
_skin_db: [Object],
_collection_args: [Object],
id: [Object],
emitter: [Object] },
options: {} },
type: 'findOne',
opts: { fields: {}, safe: true },
domain: null,
_events:
{ error: [ [Function], [Function] ],
success: [ [Function], [Function] ] },
_maxListeners: 10,
emitted: {},
ended: false,
success: [Function],
error: [Function],
complete: [Function],
resolve: [Function],
fulfill: [Function],
reject: [Function],
query: { _id: 54dcad6de4b01007caacb0cd } }
I've also tried user.query.email but get the same result.
The findById obviously doesn't return a JSON object that I can use in this way.
How can I get at these fields?
It's an async call, so you need to use the callback, you can't assign that function to a variable:
users.findById(req.body.user_id,function(e,doc){
var user = doc;
console.log(user); //should see the object now, and access the props
});
Thanks in advance for your help on this, it's much appreciated!
I'm using Node.js, MongoDB and Mongoose in a new project and I'm simply trying to find() the documents in a database. For brevity I'll just include the Mongoose code below (I'm not doing much more than this anyway right now):
var mongoose = require('mongoose');
mongoose.connect('mongodb://<username>:<password>#<sub-domain>.mongolab.com:<port>/<db>');
var schema = { email_address: String, invite: String }
, Users = mongoose.model('Users', new mongoose.Schema(schema));
console.log(Users.findOne({ 'email_address': 'jonathon#foo.bar' }, function(err, doc) { return doc; }));
I'm quite sure that should just echo the returned doc to the Node.js console (Terminal) but instead I'm getting this:
{ options: { populate: {} },
safe: undefined,
_conditions: { email_address: 'jonathon#foo.bar' },
_updateArg: {},
_fields: undefined,
op: 'findOne',
model:
{ [Function: model]
modelName: 'Users',
model: [Function: model],
options: undefined,
db:
{ base: [Object],
collections: [Object],
models: {},
replica: false,
hosts: null,
host: '<sub-domain>.mongolab.com',
port: <port>,
user: '<username>',
pass: '<password>',
name: '<db>',
options: [Object],
_readyState: 2,
_closeCalled: false,
_hasOpened: false,
db: [Object] },
schema:
{ paths: [Object],
subpaths: {},
virtuals: [Object],
nested: {},
inherits: {},
callQueue: [],
_indexes: [],
methods: {},
statics: {},
tree: [Object],
_requiredpaths: undefined,
options: [Object] },
collection:
{ collection: null,
name: 'users',
conn: [Object],
buffer: true,
queue: [Object],
opts: {} },
base:
{ connections: [Object],
plugins: [],
models: [Object],
modelSchemas: [Object],
options: {},
Collection: [Function: NativeCollection],
Connection: [Function: NativeConnection],
version: '3.5.4',
Mongoose: [Function: Mongoose],
Schema: [Object],
SchemaType: [Object],
SchemaTypes: [Object],
VirtualType: [Function: VirtualType],
Types: [Object],
Query: [Object],
Promise: [Function: Promise],
Model: [Object],
Document: [Object],
Error: [Object],
mongo: [Object] } } }
Obviously I've just obfuscated my real credential with the <username> bits, they are all correct in my code.
The database does have a document in it that would match the condition though even removing the condition from the findOne method yields no results!
I'm fairly new to Node.js so I you could explain your answers so I know for next time it'd be a great help! Thanks!
Change your code to:
Users.findOne({ 'email_address': 'jonathon#foo.bar' }, function(err, doc) {
console.log(doc);
});
I can't see from your code, but I think you are writing the value of the mongoose function to the console...
I totally forget, Node.js is asynchronous so the line console.log(Users.findOne({ 'email_address': 'jonathon#foo.bar' }, function(err, doc) { return doc; })); is indeed echoing to the console though no documents have been returned by the DB yet!
Instead the console.log method should be inside the find's callback, a la:
Users.find({}, function(err, doc) { console.log(doc); });