Have a problem with using another method in class.
I'm working with express framework and have to use Ecma Script 6.
When I try to use method in the same class I have an error:
Cannot read property 'generatePassword' of undefined
TypeError: Cannot read property 'generatePassword' of undefined
at createUser (E:\OpenServer\domains\testNode\app\controllers\users.js:5:13)
at Layer.handle [as handle_request] (E:\OpenServer\domains\testNode\node_modules\express\lib\router\layer.js:95:5)
at next (E:\OpenServer\domains\testNode\node_modules\express\lib\router\route.js:131:13)
at Route.dispatch (E:\OpenServer\domains\testNode\node_modules\express\lib\router\route.js:112:3)
at Layer.handle [as handle_request] (E:\OpenServer\domains\testNode\node_modules\express\lib\router\layer.js:95:5)
at E:\OpenServer\domains\testNode\node_modules\express\lib\router\index.js:277:22
at Function.process_params (E:\OpenServer\domains\testNode\node_modules\express\lib\router\index.js:330:12)
at next (E:\OpenServer\domains\testNode\node_modules\express\lib\router\index.js:271:10)
at Function.handle (E:\OpenServer\domains\testNode\node_modules\express\lib\router\index.js:176:3)
at router (E:\OpenServer\domains\testNode\node_modules\express\lib\router\index.js:46:12)
My code:
Route: /routes/users.js
const express = require('express');
const router = express.Router();
const users = require('../app/controllers/users');
router.get('/', users.createUser);
module.exports = router;
Controller: /app/controllers/users.js
class Users
{
createUser(req, res)
{
this.generatePassword();
res.json({msg: "The method return user data" });
}
generatePassword()
{
return 'The method return new password';
}
}
module.exports = new Users();
Main App file: /app.js
const express = require('express');
const path = require('path');
const favicon = require('serve-favicon');
const logger = require('morgan');
const cookieParser = require('cookie-parser');
const bodyParser = require('body-parser');
const index = require('./routes/index');
const users = require('./routes/users');
const app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'hbs');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', index);
app.use('/users', users);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
let err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
package.json
{
"name": "testnode",
"version": "0.0.0",
"private": true,
"scripts": {
"start": "node ./bin/www"
},
"dependencies": {
"body-parser": "~1.15.2",
"cookie-parser": "~1.4.3",
"debug": "~2.2.0",
"express": "~4.14.0",
"hbs": "~4.0.1",
"morgan": "~1.7.0",
"serve-favicon": "~2.3.0"
}
}
Help me please, thank you.
In the line that causes the error, the object this is not what you think it is. To solve this, replace the following:
router.get('/', users.createUser);
with:
router.get('/', users.createUser.bind(users));
This will make sure when eventually that function is called by the router.get implementation, it will be called with the this object set to users.
Related
All my projects were working fine before but all of sudden the content of the body is not being saved as if the body is not being parsed or something. Just to check I created this simple project of book directory but no luck.
Any help would be appreciated.
Thank you
app.js
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var mongoose = require('mongoose');
var config = require('./config');
// import bodyParser from "body-parser";//for typscript code only, use require for js
// app.use(bodyParser.json());
// app.use(bodyParser.urlencoded({ extended: false }));
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var bookRouter = require('./routes/books_routes');
const url = config.mongoURL;
const connect = mongoose.connect(url);
connect.then((DB)=>{
console.log("Connected With the MongoDB Server");
},(err)=>{next(err)})
.catch((err)=>next(err));
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(logger('dev'));
app.use(cookieParser());
app.use(express.json());
app.use(express.urlencoded({
extended: true
})); //Parse URL-encoded bodies
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', indexRouter);
app.use('/users', usersRouter);
app.use('/books',bookRouter);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
Route File
const express = require('express');
const mongoose =require('mongoose');
const Books = require('../models/books');
const bookrouter = express.Router();
// bookrouter.use(bodyparser.json());
bookrouter.use(express.json());
bookrouter.use(express.urlencoded({
extended: true
})); //Parse URL-encoded bodies
bookrouter.route('/')
.get((req,res,next)=>{
Books.find({})
.then((books)=>{
res.statusCode = 200;
res.setHeader('content-Type','application/json');
res.json(books);
},(err)=>{next(err)})
.catch((err)=>next(err))
})
.post((req,res,next)=>{
var book = new Books({
book_name: req.body.book_name,
book_author: req.body.book_author,
book_description: req.body.book_description
})
book.save()
.then((book)=>{
Books.findById(book._id)
.then((book)=>{
res.statusCode = 200;
res.setHeader('content-type','application/json');
res.json(book);
},(err)=>next(err))
})
})
.put((req,res,next)=>{
res.send("PUT request is not supported at this API");
})
.delete((req,res,next)=>{
Books.remove({})
.then((resp)=>{
res.statusCode=200;
res.setHeader('content-type','application/json');
res.send(resp);
})
})
module.exports = bookrouter;
Model file
const mongoose = require('mongoose');
var Schema = mongoose.Schema;
var passportlocalmongoose = require('passport-local-mongoose');
var Books = new Schema({
book_name :{
type:String
},
book_author:{
type:String
},
book_description:{
type:String
}
},{
timestamps:true
})
Books.plugin(passportlocalmongoose);
module.exports = mongoose.model('Book',Books);
package.json
{
"name": "books-directory",
"version": "0.0.0",
"private": true,
"scripts": {
"start": "node ./bin/www"
},
"dependencies": {
"body-parser": "^1.19.0",
"cookie-parser": "~1.4.4",
"debug": "~2.6.9",
"express": "~4.16.1",
"http-errors": "~1.6.3",
"jade": "~1.11.0",
"mongodb": "^3.0.10",
"mongoose": "^5.1.7",
"mongoose-currency": "^0.2.0",
"morgan": "~1.9.1",
"passport": "^0.4.0",
"passport-local": "^1.0.0",
"passport-local-mongoose": "^5.0.1"
}
}
I used express-generator and the following are app.js:
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var cors = require('cors');
var app = express();
app.use(cors());
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
app.use('/', indexRouter);
app.use('/users', usersRouter);
// catch 404 and forward to error handler
app.use(function (req, res, next) {
next(createError(404));
});
// error handler
app.use(function (err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
And when access to http://localhost:5000/api/ got Error:
Not Found
404
NotFoundError: Not Found
at D:\_projects\booking-system\api\app.js:28:8
at Layer.handle [as handle_request] (D:\_projects\booking-system\api\node_modules\express\lib\router\layer.js:95:5)
at trim_prefix (D:\_projects\booking-system\api\node_modules\express\lib\router\index.js:317:13)
at D:_projects\booking-system\api\node_modules\express\lib\router\index.js:284:7
at Function.process_params (D:_projects\booking-system\api\node_modules\express\lib\router\index.js:335:12)
at next (D:_projects\booking-system\api\node_modules\express\lib\router\index.js:275:10)
at D:_projects\booking-system\api\node_modules\express\lib\router\index.js:635:15
at next (D:_projects\booking-system\api\node_modules\express\lib\router\index.js:260:14)
at Function.handle (D:_projects\booking-system\api\node_modules\express\lib\router\index.js:174:3)
at router (D:_projects\booking-system\api\node_modules\express\lib\router\index.js:47:12)
Following is routes/index:
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', { title: 'API' });
});
module.exports = router;
Thank you very much for your helps !
The issue is that you define a GET / route in your routes/index.js file and then register it as app.use('/', indexRouter) in your app.js.
So you either change your routes/index.js file to it looks like this:
var express = require('express');
var router = express.Router();
// Note the /api
router.get('/api', function(req, res, next) {
res.render('index', { title: 'API' });
});
module.exports = router;
Or you keep routes/index as it is but your change the way your register it in your main.js to this:
// ...
// Note the /api
app.use('/api', indexRouter);
app.use('/users', usersRouter);
// ...
I'm setting up a new server with node js and the framework express (Version 4.16). I want to route my Rest-Endpoints. In my route.js-file i want to call a function from app.js(my Server), but getting a Typeerror where the function, that i want to call from another file, is not a function.
Error:
TypeError: callFunction.getDataFromDb is not a function
at C:\Users\---\WebstormProjects\pwa_node_server\routes\recipes.js:7:18
at Layer.handle [as handle_request] (C:\Users\---\WebstormProjects\pwa_node_server\node_modules\express\lib\router\layer.js:95:5)
at next (C:\Users\---\WebstormProjects\pwa_node_server\node_modules\express\lib\router\route.js:137:13)
at Route.dispatch (C:\Users\---\WebstormProjects\pwa_node_server\node_modules\express\lib\router\route.js:112:3)
at Layer.handle [as handle_request] (C:\Users\---\WebstormProjects\pwa_node_server\node_modules\express\lib\router\layer.js:95:5)
at C:\Users\---\WebstormProjects\pwa_node_server\node_modules\express\lib\router\index.js:281:22
at Function.process_params (C:\Users\---\WebstormProjects\pwa_node_server\node_modules\express\lib\router\index.js:335:12)
at next (C:\Users\---\WebstormProjects\pwa_node_server\node_modules\express\lib\router\index.js:275:10)
at Function.handle (C:\Users\---\WebstormProjects\pwa_node_server\node_modules\express\lib\router\index.js:174:3)
at router (C:\Users\---\WebstormProjects\pwa_node_server\node_modules\express\lib\router\index.js:47:12)
My server:
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var axios = require('axios');
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var recipesRouter = require('./routes/recipes');
var cors = require('cors');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({extended: false}));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use(cors({credentials: true, origin: true}));
app.use('/', indexRouter);
app.use('/users', usersRouter);
app.use('/recipes', recipesRouter);
// app.use('/poste-dein-rezept', indexRouter);
// catch 404 and forward to error handler
app.use(function (req, res, next) {
console.log("catch404");
next(createError(404));
});
// error handler
app.use(function (err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
var getDataFromDb = function (res) { // This function to call in another file
};
module.export = {
getDataFromDb
};
module.exports = app;
My route-file:
var express = require('express');
========
var router = express.Router();
var callFunction = require('../app');
router.get('/', function(req, res, next) {
console.log('Recipes-Endpoint received Request');
callFunction.getDataFromDb(res);
});
module.exports = router;
I just want to call a function from another file.
You're using module.export. The Correct property name is module.exports, which you are also using.
One way to solve this is:
app.getDataFromDb = getDataFromDb;
module.exports = app;
Error: Failed to lookup view "error" in views directory "/var/www/html/mean/mean-secure1/views"
at Function.render (/var/www/html/mean/mean-secure1/node_modules/express/lib/application.js:581:17)
at ServerResponse.render (/var/www/html/mean/mean-secure1/node_modules/express/lib/response.js:1008:7)
at /var/www/html/mean/mean-secure1/app.js:50:7
at Layer.handle_error (/var/www/html/mean/mean-secure1/node_modules/express/lib/router/layer.js:71:5)
at trim_prefix (/var/www/html/mean/mean-secure1/node_modules/express/lib/router/index.js:315:13)
at /var/www/html/mean/mean-secure1/node_modules/express/lib/router/index.js:284:7
at Function.process_params (/var/www/html/mean/mean-secure1/node_modules/express/lib/router/index.js:335:12)
at next (/var/www/html/mean/mean-secure1/node_modules/express/lib/router/index.js:275:10)
at /var/www/html/mean/mean-secure1/app.js:39:3
at Layer.handle [as handle_request] (/var/www/html/mean/mean-secure1/node_modules/express/lib/router/layer.js:95:5)
at trim_prefix (/var/www/html/mean/mean-secure1/node_modules/express/lib/router/index.js:317:13)
at /var/www/html/mean/mean-secure1/node_modules/express/lib/router/index.js:284:7
at Function.process_params (/var/www/html/mean/mean-secure1/node_modules/express/lib/router/index.js:335:12)
at next (/var/www/html/mean/mean-secure1/node_modules/express/lib/router/index.js:275:10)
at SendStream.error (/var/www/html/mean/mean-secure1/node_modules/serve-static/index.js:121:7)
at SendStream.emit (events.js:182:13)
app.js
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var bodyParser = require('body-parser');
var morgan = require('morgan');
var mongoose = require('mongoose');
var passport = require('passport');
var config = require('./config/database');
var api = require('./routes/api');
var app = express();
//app.set('view engine', 'pug');
mongoose.Promise = require('bluebird');
mongoose.connect(config.database, { promiseLibrary: require('bluebird') })
.then(() => console.log('connection succesful'))
.catch((err) => console.error(err));
app.use(passport.initialize());
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({'extended':'false'}));
app.use(express.static(path.join(__dirname, 'dist')));
app.use('/books', express.static(path.join(__dirname, 'dist')));
app.use('/api', api);
//app.use(express.static(path.join(_dirname, 'public')));
app.set('views', path.join(__dirname, 'views'));
app.engine('html', require('ejs').renderFile);
app.set('view engine', 'html');
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
If you want to use ejs templating as your view engine then you can use below code to set the view engine for your node application
const ejs=require("ejs");
app.set('view engine','ejs');
I'm building an app with node/express/mongo/mongoose. I've encountered an error that I can't seem to figure out and googling around has so far not been helpful.
I've created a simplistic, cat-themed example to recreate the error I'm encountering. I'm basically trying to retrieve an object by its ObjectId. I'm using the object id (as a string) that was automatically generated when I created the object.
When I navigate to the path localhost:3000/kitty/586d62878fc14d30e0ac5379 I get the following error: 'Cast to ObjectId failed for value "586d62878fc14d30e0ac5379" at path "_id" for model "Kitten"'. The offending line of code is my call to model.Kitten.findById() [see below].
As far as I can tell, the ObjectId string is valid.
I've tried casting my string object id to a mongoose object id and passing this in to findById instead of the string value, but this only produces a strange "hex is not a function" error, and besides, I am under the impression that this is unnecessary because mongoose automatically casts a valid string id to an object id.
I'm using a hosted mongodb instance (mlab).
Here is my code for reference:
Package.json:
{
"name": "testapp",
"version": "0.0.0",
"private": true,
"scripts": {
"start": "node ./bin/www"
},
"dependencies": {
"body-parser": "~1.15.2",
"cookie-parser": "~1.4.3",
"debug": "~2.2.0",
"express": "~4.14.0",
"jade": "~1.11.0",
"mongodb": "^2.2.19",
"mongoose": "^4.7.6",
"morgan": "~1.7.0",
"serve-favicon": "~2.3.0"
}
}
app.js:
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var index = require('./routes/index');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', index);
app.use('/users', users);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
index.js:
var express = require('express');
var router = express.Router();
var model = require('./model');
var mongoose = require('mongoose');
/* GET home page. */
router.get('/kitty/create', function(req, res, next) {
var fluffy = new model.Kitten({ name: 'fluffy' });
fluffy.save(function(err, fluffy){
if(err) return next(err);
res.render('index', { title: 'Express' });
});
});
router.get('/kitty/:id', function(req, res, next){
// find kitty by id
model.Kitten.findById(req.params.id, function(err, kitty){
if(err) return next(err);
if(!kitty){
res.send('no kitty found');
} else {
res.send(kitty._id);
}
});
});
module.exports = router;
model.js:
var mongoose = require('mongoose');
mongoose.connect('mongodb://xxxxx:xxxxx#xxxxx.mlab.com:xxxxx/xxxxx');
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function() {
var kittySchema = mongoose.Schema({
name: String
});
var Kitten = mongoose.model('Kitten', kittySchema);
exports.Kitten = Kitten;
});
Any insight you can offer would be greatly appreciated.
I was having the exact same problem. There seems to be an issue with mongoose version. I downgraded from 4.7.6 to 4.7.2 (the last version I was using before upgrading) and no more problem.
I don't know exactly in which version the problem was introduced, but based on the absence of answers when googling, maybe it's 4.7.6 (released on 2017-01-02).
Just doing
npm install --save mongoose#4.7.2
will fix it for now.
Hope this helps :)
Edit:
It's definitely a bug on versions after 4.7.2
https://github.com/Automattic/mongoose/issues/4867#issuecomment-270342054