I am getting an error when calling my router from my routes directory whenever i try to initialize a route with app.use(). The error i am getting says Router.use() requires a middleware function but got a Object. I've read that this could be due to me not exporting the module correctly. However i am not sure what exactly is wrong with my code below. Im pretty sure the error is in how i have the controller architected. I've tried using module.exports instead but keep getting the error. What could i try to fix this?
Error:
Users/name/Desktop/personal/app/server/src/node_modules/express/lib/router/index.js:458
throw new TypeError('Router.use() requires a middleware function but got a ' + gettype(fn))
^
TypeError: Router.use() requires a middleware function but got a Object
at Function.use (/Users/name/Desktop/personal/app/server/src/node_modules/express/lib/router/index.js:458:13)
at Function.<anonymous> (/Users/name/Desktop/personal/app/server/src/node_modules/express/lib/application.js:220:21)
at Array.forEach (<anonymous>)
at Function.use (/Users/name/Desktop/personal/app/server/src/node_modules/express/lib/application.js:217:7)
at module.exports (/Users/name/Desktop/personal/app/server/src/routes/router.js:18:7)
at Object.<anonymous> (/Users/name/Desktop/personal/app/server/src/app.js:60:1)
at Module._compile (module.js:660:30)
at loader (/Users/name/Desktop/personal/app/server/node_modules/babel-register/lib/node.js:144:5)
at Object.require.extensions.(anonymous function) [as .js] (/Users/name/Desktop/personal/app/server/node_modules/babel-register/lib/node.js:154:7)
at Module.load (module.js:573:32)
at tryModuleLoad (module.js:513:12)
at Function.Module._load (module.js:505:3)
at Function.Module.runMain (module.js:701:10)
at Object.<anonymous> (/Users/name/Desktop/personal/app/server/node_modules/babel-cli/lib/_babel-node.js:154:22)
at Module._compile (module.js:660:30)
at Object.Module._extensions..js (module.js:671:10)
[nodemon] app crashed - waiting for file changes before starting...
My route.js file that contains all my route methods. In app.js: I use import router from './routes/router'; then call this with: router(app);
import express from 'express'
import feed from '../controllers/feed.controller'
import file from '../controllers/file.controller'
import flight from '../controllers/flight.controller'
module.exports = function (app) {
// Initializing route groups
const apiRoutes = express.Router(),
feedRoutes = express.Router(),
fileRoutes = express.Router(),
flightRoutes = express.Router(),
indexRoutes = express.Router();
//= ========================
// Feed Routes
//= ========================//
apiRoutes.use('/feeds', feed);
apiRoutes.use('/downloads', feed);
// Find all feeds
feedRoutes.get('/', feed.list_all_feeds);
// Find one feed
feedRoutes.get('/:id', feed.list_one_feed);
// Find one Audience
feedRoutes.get('/:id/:audienceId', feed.list_one_feed_audience);
// Download one Feed
feedRoutes.get('/:id/download', feed.download_one_feed);
//= ========================
// File Routes
//= ========================//
apiRoutes.use('/files', file);
// Find all files
fileRoutes.get('/', file.list_all_files);
// Find one file
fileRoutes.get('/:id', file.list_one_file);
//= ========================
// Flight Routes
//= ========================//
apiRoutes.use('/flights', flight);
// Find all flights
flightRoutes.get('/', flight.list_all_flights);
// Find one flight
flightRoutes.get('/:id', flight.list_one_flight);
//= ========================
// Index Routes
//= ========================//
// Set Main index Route
apiRoutes.use('/',
indexRoutes.get('/', function(req, res, next) { res.render('index', { title: 'Express', layout: 'layout.hbs' }) })
);
// Set url for API group routes
app.use('/', apiRoutes);
}
An example of one of my controllers. (all contain the same pattern):
import express from 'express'
import mongoose from 'mongoose'
// models
import Flight from '../models/flight.model'
exports.list_all_flights = function(req, res) {
Flight.find({})
.exec(function(err, dbflights){
if(err) {
res.send('error has occured in router');
} else {
console.log('successful get from routes/flights.js ...');
res.json(dbflights);
}
});
};
exports.list_one_flight = function(req, res) {
Flight.findOne({'name': req.params.id})
.exec(function(err, dbflights){
if(err){
res.send('get error has occured in routes/feeds.js');
} else {
res.json(dbflights);
}
});
};
Instead of mounting the objects, might just mount the routes instead? So replace:
apiRoutes.use('/feeds', feed);
with:
apiRoutes.use('/feeds', feedRoutes);
Related
I'm new to Javascript. I'm trying to load the following script using Node.js (ver. 0.8.8, it has to be done in this specific version), OS - Windows 10:
//require('look').start();
var main = require('skilap-core');
if (process.argv[2]=="automated") {
process.on("message",function (msg) {
if (msg.c == "startapp") {
var app = main.createApp(msg.data);
app.startApp(__dirname+"/data",function (err) {
process.send({c:"startapp_repl",data:err})
});
}
})
} else {
var app = main.createApp();
app.startApp(__dirname+"/data",function (err) {
if (err) console.log(err);
});
module.exports = app;
}
But I get the following error:
> TypeError: Object #<Object> has no method 'createApp'
at Object.<anonymous> D:\Downloads\skilap\skilap\app.js:13:17)
at Module._compile (module.js:449:26)
at Object.Module._extensions..js (module.js:467:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Module.runMain (module.js:492:10)
at process.startup.processNextTick.process._tickCallback(node.js:244:9)
As I understand, the module loads correctly, but doesn't compile. I've done research in the web and also saw other related questions on this site, but I cannot see what the problem actually is. What does the error mean and what needs to be changed to launch the app? Any help would be appreciated.
You require a module I've never heard of:
var main = require('skilap-core');
This is a javascript object. In your code you are trying to call a createApp() method on that object:
var app = main.createApp();
The main object does not have the createApp() function.
I would use a debugger or insert a console.log(main) after the require to see what the object actually looks like.
I used npm pack skilap-core to download it as a tgz file and examine it. There doesn't appear to be a createApp() function at all. It appears to want to take some kind of custome webapp as a parameter:
module.exports = function (webapp) {
var app = webapp.web;
var ctx = webapp._ctx;
var prefix = webapp.prefix;
var api = webapp;
app.get(prefix, function (req, res, next) {
res.redirect(prefix+"/user");
})
app.get("/", webapp.layout(), function(req, res, next) {
...
I changed the line var main = require('skilap-core') to var main = require('./modules/core/lib/core.js') (the path to the module file) and the module started working.
I am creating an API, so I want to add a user system and validate access to the API.
This would be the middleware for validation:
'use strict'
const jwt = require('jwt-simple');
const moment = require('moment');
const config = require('../settings/config');
function isAuth(req, res, next) {
if (!req.headers.authotization) {
return res.status(403).send({
message: `No tiene autorizacion`
})
}
const token = req.headers.authotization.split(" ")[1];
const payload = jwt.decode(token, user, config.token.secret_token);
if (payload.exp <= moment().unix()) {
return res.status(401).send({
message: 'El token ha expirado'
})
req.user = payload.sub;
next();
}
}
module.exports = isAuth;
while this would be the route:
'use strict'
const express = require('express');
const router = express.Router();
const auth = require('../middlewares/auth');
router.get('/', auth.isAuth, (req, res) => {
res.status(200).send({
message: `Tienes acceso`
})
})
on the other hand, this is my main application settings (app.js):
const express = require('express');
const bodyParser = require('body-parser');
const morgan = require('morgan');
const app = express();
const config = require('./config')
// Middleware
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(morgan('dev'));
// Routes variables
const productRouter = require('../routes/product');
const privateRouter = require('../routes/private');
// Routes uses
app.use('/api/product', productRouter);
app.use('/private', privateRouter);
app.listen(config.app.port, err => {
if (err) throw err;
console.log(`Server listening on port ${config.app.port}`)
})
module.exports = app;
I am getting this error:
D:\api-rest-carlos-azaustre\node_modules\express\lib\router\route.js:202
throw new Error(msg);
^
Error: Route.get() requires a callback function but got a [object
Undefined]
at Route. [as get] (D:\api-rest-carlos-azaustre\node_modules\express\lib\router\route.js:202:15)
at Function.proto. [as get] (D:\api-rest-carlos-azaustre\node_modules\express\lib\router\index.js:510:19)
at Object. (D:\api-rest-carlos-azaustre\routes\private.js:6:8)
at Module._compile (internal/modules/cjs/loader.js:959:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:995:10)
at Module.load (internal/modules/cjs/loader.js:815:32)
at Function.Module._load (internal/modules/cjs/loader.js:727:14)
at Module.require (internal/modules/cjs/loader.js:852:19)
at require (internal/modules/cjs/helpers.js:74:18)
at Object. (D:\api-rest-carlos-azaustre\settings\app.js:15:23)
at Module._compile (internal/modules/cjs/loader.js:959:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:995:10)
at Module.load (internal/modules/cjs/loader.js:815:32)
at Function.Module._load (internal/modules/cjs/loader.js:727:14)
at Module.require (internal/modules/cjs/loader.js:852:19)
at require (internal/modules/cjs/helpers.js:74:18) [nodemon] app crashed - waiting for file changes before starting...
And sometimes this line is added at the top of error:
(node:3092) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 exit listeners > added to [Bus]. Use emitter.setMaxListeners() to increase limit
After reading the answers, I edit my question. I have placed only auth and not auth.isAuth and I am getting the following error:
D:\api-rest-carlos-azaustre\node_modules\express\lib\router\index.js:458
throw new TypeError('Router.use() requires a middleware function but got a ' + gettype(fn))
^
TypeError: Router.use() requires a middleware function but got a
Object
at Function.use (D:\api-rest-carlos-azaustre\node_modules\express\lib\router\index.js:458:13)
at Function. (D:\api-rest-carlos-azaustre\node_modules\express\lib\application.js:220:21)
at Array.forEach ()
at Function.use (D:\api-rest-carlos-azaustre\node_modules\express\lib\application.js:217:7)
at Object. (D:\api-rest-carlos-azaustre\settings\app.js:20:5)
at Module._compile (internal/modules/cjs/loader.js:959:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:995:10)
at Module.load (internal/modules/cjs/loader.js:815:32)
at Function.Module._load (internal/modules/cjs/loader.js:727:14)
at Module.require (internal/modules/cjs/loader.js:852:19)
at require (internal/modules/cjs/helpers.js:74:18)
at Object. (D:\api-rest-carlos-azaustre\index.js:3:13)
at Module._compile (internal/modules/cjs/loader.js:959:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:995:10)
at Module.load (internal/modules/cjs/loader.js:815:32)
at Function.Module._load (internal/modules/cjs/loader.js:727:14) [nodemon] app crashed - waiting for file changes before starting...
Does anybody know what is it due to?
module.exports = isAuth; means you're only exporting the function and nothing else. That means when you do const auth = require('../middlewares/auth');, auth is the actual function, not an object containing isAuth as a property.
So, doing router.get('/', auth, (req, res) => { should work, instead of auth.isAuth which is invalid.
Learn more about modules here: https://js.evie.dev/modules
Yes, you export the function with this code: module.exports = isAuth;
But then you call use it like this: auth.isAuth
Assuming you're doing something like const auth = require('./bin/auth.js'); or whatever
auth would be the function itself -- there will be no isAuth property.
So you should try this:
router.get('/', auth, (req, res) => {
You haven't posted your entire code, so this is just a best guess.
I am following a tutorial on how to set up a basic mvc in Nodejs using the hapi server and a few other packages.
Tutorial: https://www.sitepoint.com/node-js-mvc-application/
Git for my project: https://github.com/christoph88/node-js-mvc-tut/
I have an error when I try to launch the server:
~/Projects/node-js-mvc-tut$ node server.js
/home/christoph/Projects/node-js-mvc-tut/server.js:33
Models.sequelize.sync().then(() => {
^
TypeError: Cannot read property 'sync' of undefined
at Object.<anonymous> (/home/christoph/Projects/node-js-mvc-tut/server.js:33:17)
at Module._compile (module.js:569:30)
at Object.Module._extensions..js (module.js:580:10)
at Module.load (module.js:503:32)
at tryModuleLoad (module.js:466:12)
at Function.Module._load (module.js:458:3)
at Function.Module.runMain (module.js:605:10)
at startup (bootstrap_node.js:158:16)
at bootstrap_node.js:575:3
Model is defined within the requirements. I do not understand why sync is undefined. Sequelise is required within the lib/index.js file.
'use strict';
const Hapi = require('hapi');
const Hoek = require('hoek');
const Path = require('path');
const Settings = require('./settings');
const Routes = require('./lib/routes');
const Models = require('./lib/models/');
const server = new Hapi.Server();
server.connection({ port: Settings.port });
server.register([
require('vision'),
require('inert')
], (err) => {
Hoek.assert(!err, err);
server.views({
engines: { pug: require('pug') },
path: Path.join(__dirname, 'lib/views'),
compileOptions: {
pretty: false
},
isCached: Settings.env === 'production'
});
// Add routes
server.route(Routes);
});
Models.sequelize.sync().then(() => {
server.start((err) => {
Hoek.assert(!err, err);
console.log(`Server running at: ${server.info.uri}`);
});
});
Can somebody help me with this? Would be great to get this running so I can try to adapt it to my needs.
I have got it working by moving my index.js file to the models folder.
This file has the necessairy scripts that dispatches sequelise in the model thus fixing the problem.
Make sure you have exported the db in index.js
module.exports = db
and declared a db variable at the beginning of the file
var db = {}
I'm making an API that accepts a video and uploads it to cloudinary. Meta data about the upload is then returned to the user. The problem that I am having occurs when I try to handle the video in middleware. I'm not sure why I keep getting this error.
The error:
/Users/name/test/cloudinary_upload/node_modules/express/lib/router/route.js:196
throw new Error(msg);
^
Error: Route.post() requires callback functions but got a [object Object]
at Route.(anonymous function) [as post] (/Users/name/test/cloudinary_upload/node_modules/express/lib/router/route.js:196:15)
at Function.proto.(anonymous function) [as post] (/Users/name/test/cloudinary_upload/node_modules/express/lib/router/index.js:510:19)
at Object.<anonymous> (/Users/name/test/cloudinary_upload/routes.js:8:8)
at Module._compile (module.js:541:32)
at Object.Module._extensions..js (module.js:550:10)
at Module.load (module.js:458:32)
at tryModuleLoad (module.js:417:12)
at Function.Module._load (module.js:409:3)
at Module.require (module.js:468:17)
at require (internal/module.js:20:19)
PROJECT CODE BELOW:
app.js
'use strict';
var express = require('express');
var formidable = require('express-formidable');
var port = process.env.PORT || 3000;
var routes = require('./routes');
var app = express();
// Parse incoming request
app.use(formidable());
app.use('/routes', routes);
// 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) {
res.status(err.status || 500);
res.json({
error: {
message: err.message
}
});
});
app.listen(port, function() {
console.log('Express server is listening on port ' + port);
});
routes.js
'use strict';
var express = require('express');
var createThumbnail = require('./middleware/generatevideothumbnail');
var uploadToCloudinary = require('./middleware/uploadtocloudinary');
var router = express.Router();
router.post('/upload', uploadToCloudinary, createThumbnail, function(req, res, next) {
console.log(req.cloudinaryObject);
console.log(req.videoThumbnail);
res.json(req.cloudinaryObject);
});
module.exports = router;
uploadtocloudinary.js
'use strict';
var cloudinary = require('../cloudinary_config.js').cloudinary;
/************************************************************
MIDDLEWARE: Accepts the request object. Uploads the video
file to cloudinary. Passes the video's public id, version, file
type, time of upload, file size and url to the next middleware
on the request object.
************************************************************/
function uploadToCloudinary(req, res, next) {
cloudinary.uploader.upload(req.files.fileToUpload.path, function(resultOfUpload) {
var cloudinaryObject = {
public_id: resultOfUpload.public_id,
version: resultOfUpload.version,
typeOfFile: resultOfUpload.format, // Type of file
uploadTime: resultOfUpload.created_at, // Upload time
fileSize: resultOfUpload.bytes, // File size
videoUrl: resultOfUpload.secure_url // Video URL
}
req.cloudinaryObject = cloudinaryObject;
next();
}, {
resource_type: "video"
});
}
module.exports.uploadToCloudinary = uploadToCloudinary;
generatevideothumbnail.js
'use strict';
/************************************************************
MIDDLEWARE: Accepts the request object. Use the version and
public id of video to create thumbnail url string. Pass
thumbnail url to next middleware on the request object.
************************************************************/
function generateVideoThumbnail(req, res, next) {
req.videoThumbnail = "https://res.cloudinary.com/xxxxxxxxx/video/upload/v"
+ req.cloudinaryObject.version
+ "/"
+ req.cloudinaryObject.public_id
+ ".jpg";
next()
}
module.exports.generateThumbnail = generateVideoThumbnail;
There are a few different choices of what to send with your required file when you use module.exports. You can send an entire object, or you can send specific functions.
With module.exports.uploadToCloudinary= and module.exports.generateThumbnail= you're sending an object that includes the functions uploadToCloudinary and generateThumbnail. When you require it with, for example,
var createThumbnail = require('./middleware/generatevideothumbnail');
you are able to use the function generateThumbnail on the object you're exporting. In other words, to access the function you want, you'd have to write:
createThumbnail.generateThumbnail
If you just want to be able to use only one specific function when you bring in the required file, just give the name of the function to module.exports, like this:
module.exports = generateVideoThumbnail;
Reference: https://www.sitepoint.com/understanding-module-exports-exports-node-js/ and https://nodejs.org/api/modules.html
Let me know if this makes sense.
This is my server.js code
var express = require('express');
feeds = require('./routes/whatshappeningfeed');
var http = require('http');
var pathname = require('path');
// Test services - to be removed
courses = require('./routes/courses');
auth = require('./routes/auth');
token = require('./routes/token');
var app = express();
app.configure(function () {
app.use(express.logger('dev')); /* 'default', 'short', 'tiny', 'dev' */
app.use(express.bodyParser());
});
app.use(function (error, req, res, next) {
if (!error) {
next();
} else {
console.error(error.stack);
res.send(500);
}
});
app.get('/me/whatshappeningfeed',feeds.getfeeds);
app.get('/courses', courses.findAll);
app.get('/courses/:id', courses.findById);
app.get('/token', token.auth);
app.get('/auth', auth.auth);
app.get('/refresh', auth.refresh);
app.listen(80);
console.log('Listening on port 80...');
this is my error message :
F:\NODE.JS\poc\node_modules\express\lib\router\index.js:291
throw new Error(msg);
^
Error: .get() requires callback functions but got a [object Undefined]
at F:\NODE.JS\poc\node_modules\express\lib\router\index.js:291:11
at Array.forEach (native)
at Router.route (F:\NODE.JS\poc\node_modules\express\lib\router\index.js:287:13)
at Router.(anonymous function) [as get] (F:\NODE.JS\poc\node_modules\express\lib\router\index.js:318:16)
at Function.app.(anonymous function) [as get] (F:\NODE.JS\poc\node_modules\express\lib\application.js:431:26)
at Object.<anonymous> (F:\NODE.JS\poc\server.js:44:5)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
When i run the node server.js file i got above error. it was working earlier. i couldn't sort out the issue. please anyone help me.
The error says it all, app.get() requires a callback function. So it means that one or more of your routes are missing a callback.
ALL of your routes should have a function(req,res), whether explicitely as in the example or in another function (see comments) :
app.get('/me/whatshappeningfeed', function(req,res){ //request, response
//then here you can define what your server should send as a response when queries for /me/whatshappeningfeed
res.send(feeds.getfeeds()); //this will send back to the browser the result of feeds.getfeeds()
});
Also, not sure if it's due to the copypaste you did, but the first semicolon require('express'); should be a comma.