gsiradze
gsiradze

Reputation: 4733

Router.use() requires a middleware function but got a undefined

I have this code in my index.js

...
import userRoutes from './src/routes/userRoutes';
import invoicesRoutes from './src/routes/invoicesRoutes';
import authMiddleware from "./src/middlewares/authMiddleware";
...
const app = express();
...
app.use('/user', authMiddleware, userRoutes(app));
app.use('/invoices', authMiddleware, invoicesRoutes(app));

my authmiddleware

const authMiddleware = (req, res, next) => {
    if (req.headers && req.headers.authorization && req.headers.authorization.split(' ')[0] === 'JWT') {
        console.log(req.headers.authorization.split(' ')[0]);
        next();
    } else {
        console.log('else');
        next();
    }
};

export default authMiddleware;

and one of my routes:

import { register, login } from '../controllers/authController';

const userRoutes = (app) => {
    app.route('/user/signup')
        .post(register);
    app.route('/user/login')
        .post(login);
};

export default userRoutes;

I'm getting an error:

throw new TypeError('Router.use() requires a middleware function but got a ' + gettype(fn)) ^

TypeError: Router.use() requires a middleware function but got a undefined

What's wrong?

Upvotes: 8

Views: 7500

Answers (4)

Tejasvi Manmatha
Tejasvi Manmatha

Reputation: 634

In my route.js

I had put it like this module.exports = routes;

what I intended to do was export routes, after changing it like below my error was gone module.exports = {routes};

Upvotes: 0

lix
lix

Reputation: 52

Check all your JavaScript files to make sure you are not missing this line:

module.exports = router

Upvotes: 0

YouneL
YouneL

Reputation: 8351

Express already offer the Router class to separate routes in different sub-modules, So you can import userRoutes module without passing app variable into it, here is an example:

userRoutes.js

import { register, login } from '../controllers/authController';
import express from 'express';

const router = express.Router();

router.route('/signup')
        .post(register);

router.route('/login')
        .post(login);

export default router;

index.js

...
import userRoutes from './src/routes/userRoutes';
import invoicesRoutes from './src/routes/invoicesRoutes';
import authMiddleware from "./src/middlewares/authMiddleware";
...
const app = express();
...
app.use('/user', authMiddleware, userRoutes);
app.use('/invoices', authMiddleware, invoicesRoutes);

Hope this helps

Upvotes: 0

Stamos
Stamos

Reputation: 3998

You pass your routes initialization as a middleware fuction app.use('/user', authMiddleware, userRoutes(app));

In this line of code what userRoutes(app) was supposed to return is function(req,res[,next]){}

Its should be like this

app.use('/user', authMiddleware, (req, res, next) => {
        userRoutes(app);
        next()
})

and what you do is

app.use('/user', authMiddleware, (app) => {
    app.route('/user/signup').post(register);
    app.route('/user/login').post(login);
})

that is wrong

There seems to be some bad logic here because from what I understand you will have to call http://localhost/user to initialize the routes and that will not work well beacuse of express's middleware inclusion.

Again from what I understand what you are trying to do should look more like this

...
import userRoutes from './src/routes/userRoutes';
import invoicesRoutes from './src/routes/invoicesRoutes';
...
const app = express();
userRoutes(app);
invoicesRoutes(app);

and

import { register, login } from '../controllers/authController';
import authMiddleware from "./middleware";
const userRoutes = (app) => {
    app.post('/user/signup', authMiddleware, register);
    app.post('/user/login', authMiddleware, login);
};

export default userRoutes;

Upvotes: 4

Related Questions