Nodejs middleware .pre shows not a function - node.js

var categoryList = new Referral({categoryList : category});
categoryList.pre('save', function (next) {
Referral.find({categoryList : category}, function (err, docs) {
if (!docs.length){
next();
}else{
console.log('Data exists: ', category);
next(new Error("Data exists!"));
}
})
})
Referral is my variable assigned to my schema.
categoryList is the object
This gives an error
TypeError: categoryList.pre is not a function at
D:\Aventyn\ClipCare_v2\app\api.js:112:18 at Layer.handle [as
handle_request]
(D:\Aventyn\ClipCare_v2\node_modules\express\lib\router\layer.js:95:5)
at next
(D:\Aventyn\ClipCare_v2\node_modules\express\lib\router\route.js:131:13)
at Route.dispatch
(D:\Aventyn\ClipCare_v2\node_modules\express\lib\router\route.js:112:3)
at Layer.handle [as handle_request]
(D:\Aventyn\ClipCare_v2\node_modules\express\lib\router\layer.js:95:5)
at
D:\Aventyn\ClipCare_v2\node_modules\express\lib\router\index.js:277:22
at Function.process_params
(D:\Aventyn\ClipCare_v2\node_modules\express\lib\router\index.js:330:12)
at next
(D:\Aventyn\ClipCare_v2\node_modules\express\lib\router\index.js:271:10)
at Function.handle
(D:\Aventyn\ClipCare_v2\node_modules\express\lib\router\index.js:176:3)
at router
(D:\Aventyn\ClipCare_v2\node_modules\express\lib\router\index.js:46:12)
at Layer.handle [as handle_request]
(D:\Aventyn\ClipCare_v2\node_modules\express\lib\router\layer.js:95:5)
at trim_prefix
(D:\Aventyn\ClipCare_v2\node_modules\express\lib\router\index.js:312:13)
at
D:\Aventyn\ClipCare_v2\node_modules\express\lib\router\index.js:280:7
at Function.process_params
(D:\Aventyn\ClipCare_v2\node_modules\express\lib\router\index.js:330:12)
at next
(D:\Aventyn\ClipCare_v2\node_modules\express\lib\router\index.js:271:10)
at
D:\Aventyn\ClipCare_v2\node_modules\express\lib\router\index.js:618:15

Try changing:
categoryList.pre('save', function (next) {
// ...
})
to:
categoryList.schema.pre('save', function (next) {
// ...
})
The .pre() is a method of the Mongoose schema, not a model.

Middleware (like pre hooks) are part of a schema. It looks like you're trying to use it on a single document, which is not how it works.
Instead, use it on the schema that you used to create the Referral model:
ReferralSchema.pre('save', ...);
This does mean that the pre hook will be applied to all documents of that schema.

Related

Unable to grab data from MongoDB to use on Express

I'm currently trying to grab data from MongoDB via Mongoose, and show it with Express. However, this is the following error I'm getting:
TypeError: /home/node/CSci-Project/views/account.ejs:31
29| <% if (req.user.twitter.token) { %>
30| <p>
>> 31| <strong>id</strong>: <%= user.twitter.id %><br>
32| <strong>token</strong>: <%= user.twitter.token %><br>
33| <strong>display name</strong>: <%= profile.twitter.displayName %><br>
34| <strong>username</strong>: <%= profile.twitter.username %><br>
Cannot read property 'twitter' of undefined
at eval (/home/node/CSci-Project/views/account.ejs:13:31)
at account (/home/node/CSci-Project/node_modules/ejs/lib/ejs.js:691:17)
at tryHandleCache (/home/node/CSci-Project/node_modules/ejs/lib/ejs.js:272:36)
at View.exports.renderFile [as engine] (/home/node/CSci-Project/node_modules/ejs/lib/ejs.js:489:10)
at View.render (/home/node/CSci-Project/node_modules/express/lib/view.js:135:8)
at tryRender (/home/node/CSci-Project/node_modules/express/lib/application.js:640:10)
at Function.render (/home/node/CSci-Project/node_modules/express/lib/application.js:592:3)
at ServerResponse.render (/home/node/CSci-Project/node_modules/express/lib/response.js:1012:7)
at /home/node/CSci-Project/app/routes.js:67:13
at Layer.handle [as handle_request] (/home/node/CSci-Project/node_modules/express/lib/router/layer.js:95:5)
at next (/home/node/CSci-Project/node_modules/express/lib/router/route.js:137:13)
at isLoggedIn (/home/node/CSci-Project/app/routes.js:105:16)
at Layer.handle [as handle_request] (/home/node/CSci-Project/node_modules/express/lib/router/layer.js:95:5)
at next (/home/node/CSci-Project/node_modules/express/lib/router/route.js:137:13)
at Route.dispatch (/home/node/CSci-Project/node_modules/express/lib/router/route.js:112:3)
at Layer.handle [as handle_request] (/home/node/CSci-Project/node_modules/express/lib/router/layer.js:95:5)
I thought I had passed it through with callback and with findOne being asynchronous, so I'm not sure where to go from here. Here are the relevant files:
views/account.ejs (the page I'm trying to view)
app/routes.js
app/models/user.js
app/models/profile.js
Sorry if I've made any simple mistakes in here - I'm new to Node and I've come over from C#, so I'm still in the process of learning the differences. Also worth noting that data is definitely on MongoDB and it all exists.
Well, I managed to figure it out, after countless attempts. My mistake was that I thought by putting var userInfo = UserModel.findOne it would just simply print itself out as userInfo.id, userInfo.token, etc, but no. I actually meant to use the output that's inside of UserModel.findOne.
app/routes.js
module.exports = function (app, passport) {
app.get('/account', isLoggedIn, function (req, res) {
var UserModel = require('./models/user.js');
var ProfileModel = require('./models/profile.js');
UserModel.findOne({
'twitter.id': req.user.twitter.id
}, function (err, userInfo) {
if (err) {
return res.redirect('/');
} else {
ProfileModel.findOne({
'twitter.id': req.user.twitter.id
}, function (err, profileInfo) {
if (err) {
return res.redirect('/');
} else {
res.render('account.ejs', {
req: req,
user: userInfo,
profile: profileInfo
});
}
});
}
});
});
};

Keystone Tutorial: cannot read property 'id' of undefined

I was following the tutorial on starting KeystoneJS from scratch. But when I got to the second part of the tutorial, creating data models, I got this error:
Error thrown for request: /keystone/
TypeError: Cannot read property 'id' of undefined
at IndexRoute (/root/websie/node_modules/keystone/admin/server/routes/index.js:39:16)
at Layer.handle [as handle_request] (/root/websie/node_modules/express/lib/router/layer.js:95:5)
at next (/root/websie/node_modules/express/lib/router/route.js:137:13)
at Route.dispatch (/root/websie/node_modules/express/lib/router/route.js:112:3)
at Layer.handle [as handle_request] (/root/websie/node_modules/express/lib/router/layer.js:95:5)
at /root/websie/node_modules/express/lib/router/index.js:281:22
at Function.process_params (/root/websie/node_modules/express/lib/router/index.js:335:12)
at next (/root/websie/node_modules/express/lib/router/index.js:275:10)
at /root/websie/node_modules/keystone/admin/server/app/createDynamicRouter.js:26:3
at Layer.handle [as handle_request] (/root/websie/node_modules/express/lib/router/layer.js:95:5)
at trim_prefix (/root/websie/node_modules/express/lib/router/index.js:317:13)
at /root/websie/node_modules/express/lib/router/index.js:284:7
at Function.process_params (/root/websie/node_modules/express/lib/router/index.js:335:12)
at next (/root/websie/node_modules/express/lib/router/index.js:275:10)
at handleUploadedFiles (/root/websie/node_modules/keystone/lib/uploads.js:6:54)
at Layer.handle [as handle_request] (/root/websie/node_modules/express/lib/router/layer.js:95:5)
GET /keystone/ 500 8.835 ms
Since I'm new to Keystone JS, I don't quite know if this problem is with the code itself or the database.
Things to consider:
This is run on a linux environment
MongoDB is freshly installed
These are all the files so far:
keystone.js
const keystone = require('keystone')
keystone.init({
'cookie secret': 'SECRET KEY',
'name' : 'theproject',
'user model' : 'User',
'auth' : 'true',
'auto update' : 'true',
});
keystone.import('models');
keystone.start();
User.js:
const keystone = require('keystone');
var User = new keystone.List('User');
User.add({
displayName: { type: String },
password: { type: keystone.Field.Types.Password },
email: { type: keystone.Field.Types.Email, unique: true },
})
User.schema.virtual('canAccessKeystone').get(function () {
return true;
});
User.defaultColumns = 'id, displayName, email';
User.register();
Your User model doesn't have an "id" attribute. So when you set your User.defaultColumns to "id" it doesn't find anything.
All models do however have an "_id" attribute.
I would just remove "id" from your default columns and move forward.
User.defaultColumns = 'displayName, email';
If that doesn't fix it you might be requesting the id elsewhere.

NodeJS with express, can't load model

I'm using NodeJS with express, consign, body-parser, etc.
I'm trying to load a module in a var, so i can use their functions, but i'm getting a:
TypeError: Cannot read property 'listar' of undefined
at app.get (/home/sartori/Documentos/Projetos/react-system/api/controllers/autores.js:6:11)
at Layer.handle [as handle_request] (/home/sartori/Documentos/Projetos/react-system/api/node_modules/express/lib/router/layer.js:95:5)
at next (/home/sartori/Documentos/Projetos/react-system/api/node_modules/express/lib/router/route.js:137:13)
at Route.dispatch (/home/sartori/Documentos/Projetos/react-system/api/node_modules/express/lib/router/route.js:112:3)
at Layer.handle [as handle_request] (/home/sartori/Documentos/Projetos/react-system/api/node_modules/express/lib/router/layer.js:95:5)
at /home/sartori/Documentos/Projetos/react-system/api/node_modules/express/lib/router/index.js:281:22
at Function.process_params (/home/sartori/Documentos/Projetos/react-system/api/node_modules/express/lib/router/index.js:335:12)
at next (/home/sartori/Documentos/Projetos/react-system/api/node_modules/express/lib/router/index.js:275:10)
at /home/sartori/Documentos/Projetos/react-system/api/node_modules/express-validator/lib/express_validator.js:250:5
at Layer.handle [as handle_request] (/home/sartori/Documentos/Projetos/react-system/api/node_modules/express/lib/router/layer.js:95:5)
Here's my controller:
module.exports = app => {
app.get('/api/autores', (req,res) => {
let connection = app.connection.connectionFactory();
let autores = app.models.AutoresDao(connection);
autores.listar((error,result) => {
if(error) {
console.log('Erro ao listar os autores: ' + error);
res.status(500).send(error);
} else {
res.json(result);
}
});
});
}
Here's the AutoresDao:
function AutoresDao(connection) {
this._connection = connection;
}
AutoresDao.prototype.listar = callback => this._connection.query('SELECT * FROM autores', callback);
module.exports = function() {
return AutoresDao;
}
The problem is: Cannot read property 'listar' of undefined.
Apparently the problem is loading the AutoresDao file.
I'm 100% sure of files path, AutoresDao is inside models folder, already loaded on consign. The same for the controller, connection, express config etc.
Any idea of what i'm doing wrong?
You need to be using the 'new' keyword if you are going to format your object constructor function in that manner. You will have to reformat your AutoresDao function to explicitly return an object, or use the 'new' keyword when you assign it to autores in the controller.
Please checkout this article for an explanation of the different instantiation patterns.
https://medium.com/dailyjs/instantiation-patterns-in-javascript-8fdcf69e8f9b
Hope that helps! Cheers.

strange behavior jsonwebtoken expired error

I have a Node.js application which uses jsonwebtoken for session management.
However, after the token expired, when I want to access again, I got:
{ TokenExpiredError: jwt expired
at Object.module.exports [as verify] (/home/ubuntu/me-n-you/node_modules/jsonwebtoken/verify.js:126:19)
at auth (/home/ubuntu/me-n-you/app_server/routes/index.js:14:9)
at Layer.handle [as handle_request] (/home/ubuntu/me-n-you/node_modules/express/lib/router/layer.js:95:5)
at next (/home/ubuntu/me-n-you/node_modules/express/lib/router/route.js:137:13)
at Route.dispatch (/home/ubuntu/me-n-you/node_modules/express/lib/router/route.js:112:3)
at Layer.handle [as handle_request] (/home/ubuntu/me-n-you/node_modules/express/lib/router/layer.js:95:5)
at /home/ubuntu/me-n-you/node_modules/express/lib/router/index.js:281:22
at Function.process_params (/home/ubuntu/me-n-you/node_modules/express/lib/router/index.js:335:12)
at next (/home/ubuntu/me-n-you/node_modules/express/lib/router/index.js:275:10)
at Function.handle (/home/ubuntu/me-n-you/node_modules/express/lib/router/index.js:174:3)
at router (/home/ubuntu/me-n-you/node_modules/express/lib/router/index.js:47:12)
at Layer.handle [as handle_request] (/home/ubuntu/me-n-you/node_modules/express/lib/router/layer.js:95:5)
at trim_prefix (/home/ubuntu/me-n-you/node_modules/express/lib/router/index.js:317:13)
at /home/ubuntu/me-n-you/node_modules/express/lib/router/index.js:284:7
at Function.process_params (/home/ubuntu/me-n-you/node_modules/express/lib/router/index.js:335:12)
at next (/home/ubuntu/me-n-you/node_modules/express/lib/router/index.js:275:10)
name: 'TokenExpiredError',
message: 'jwt expired',
expiredAt: 2018-05-08T21:14:27.000Z }
I repeat to get the same errors until a very long time then I could access again.
But, I can access if using another device or browser at the same time.
I have no idea how to fix it. Does anyone have any clue on this?
Thanks in advance.
Richard Xu
You can again logged in ,also if you are using bcrypt
bcrypt.compare(req.body.password, data[0].password, (err, resposne) => {
if (err) {
res.status(500).json(err);
}
//response is either true or false
if (resposne) {
const token = jwt.sign({
email: data[0].email,
userId: data[0]._id
}, "secret",
{
expiresIn: "1h"
})
return res.status(200).json({
message: 'Auth successful',
token: token
})
} else {
return res.status(401).json({ message: 'Auth failed' })
}
})
Increase your expiry limit

Cannot read property 'prototype' of undefined

I'm starting with Parse and Node.js. I'm trying to retrieve data from Parse db and I don't manage to.
var Parse = require('parse').Parse;
Parse.initialize("*************", "*****************");
module.exports = {
index: function(req, res, next){
var query = new Parse.Query(Parse.Event);
query.find({
success: function(results) {
console.log(results);
},
error: function(error) {
console.log(error.message);
}
});
}
}
And I got this error :
TypeError: Cannot read property 'prototype' of undefined
at Object.Parse.Query (/Users/tchiss_a/test/webapp/node_modules/parse/build/parse-latest.js:7771:33)
at module.exports.index (/Users/tchiss_a/test/webapp/api/Events.js:7:20)
at Layer.handle [as handle_request] (/Users/tchiss_a/test/webapp/node_modules/express/lib/router/layer.js:82:5)
at next (/Users/tchiss_a/test/webapp/node_modules/express/lib/router/route.js:100:13)
at Route.dispatch (/Users/tchiss_a/test/webapp/node_modules/express/lib/router/route.js:81:3)
at Layer.handle [as handle_request] (/Users/tchiss_a/test/webapp/node_modules/express/lib/router/layer.js:82:5)
at /Users/tchiss_a/test/webapp/node_modules/express/lib/router/index.js:235:24
at Function.proto.process_params (/Users/tchiss_a/test/webapp/node_modules/express/lib/router/index.js:313:12)
at /Users/tchiss_a/test/webapp/node_modules/express/lib/router/index.js:229:12
at Function.match_layer (/Users/tchiss_a/test/webapp/node_modules/express/lib/router/index.js:296:3)
Can someone help me please ?
There is a fix listed in the comments, but the actual problem here is that you're treating a user-defined class "Event" like a Parse class.
change
var query = new Parse.Query(Parse.Event);
to
var query = new Parse.Query("Event");

Resources