Reputation: 161
Everyone I'm beginner in NODEJS I'm trying to do small chat app.I'm facing routing problem in server.js. [ in the line app.use('/',chatcat.router); ].I have attached the error below. Can anyone tell me?.how to resolve this problem. Thanks in advance...
server.js
const express=require('express');
const app=express();
const chatcat=require('./app');
app.set('port',process.env.PORT || 8086);
app.use(express.static('public'));
app.set('view engine','ejs');
app.use('/',chatcat.router);
app.listen(app.get('port'),()=>{
console.log('server is listening on port: ',app.get('port'));
});
app/index.js
const routes=require('./routes');
module.exports={
router: routes()
}
app/routes/index.js:
'use strict';
const h=require('../helpers');
console.log('routers/index outside');
module.exports=()=>{
console.log('routers/index inside');
let routes={
'get':{
'/':(req,res,next)=>{
res.render('login');
},
'/chat':(req,res,next)=>{
res.render('chatroom');
},
'/rooms':(req,res,next)=>{
res.render('rooms');
}
} ,
'post':{
'/chat':(req,res,next)=>{
res.render('chatroom');
}
}
}
return h.route12(routes);
};
app/helpers/index.js
'use strict';
const express=require('express');
const router=express.Router();
console.log('helpers/index outside');
let _registerRoutes=(routes,method)=>{
for(let key in routes){
if( (typeof routes[key] === 'object') && (routes[key] !==null) && !( routes[key] instanceof Array)){
_registerRoutes(routes[key],key);
}
else{
if(method === 'get'){
console.log('get in');
router.get(key,routes[key]);
}
else if(method ==='post'){
console.log('post in');
router.post(key,routes[key]);
}
}
}
}
let route12=routes=>{
console.log('calling registerroutes');
_registerRoutes(routes);
}
module.exports={
route12
}
I have gotten the error like:
E:\STUDIES\Node Technologies\NodeJS\chatcat\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 undefined at Function.use (E:\STUDIES\Node Technologies\All about NodeJS\chatcat\node_modules\express\lib\router\index.js:458:13) at Function. (E:\STUDIES\Node Technologies\All about NodeJS\chatcat\node_modules\express\lib\application.js:220:21) at Array.forEach () at Function.use (E:\STUDIES\Node Technologies\All about NodeJS\chatcat\node_modules\express\lib\application.js:217:7) at Object. (E:\STUDIES\Node Technologies\All about NodeJS\chatcat\server.js:13:5) at Module._compile (module.js:653:30) at Object.Module._extensions..js (module.js:664:10) at Module.load (module.js:566:32) at tryModuleLoad (module.js:506:12) at Function.Module._load (module.js:498:3)
Upvotes: 0
Views: 1453
Reputation: 161
@jfriend00 thankyou for your valuable time to spend to solve my error.I have resolved the error as per your advice... see below the code what i changed in
app/helpers/index.js:
'use strict';
const express=require('express');
const router=express.Router();
console.log('helpers/index outside');
let _registerRoutes=(routes,method)=>{
for(let key in routes){
if( (typeof routes[key] === 'object') && (routes[key] !==null) && !( routes[key] instanceof Array)){
_registerRoutes(routes[key],key);
}
else{
if(method === 'get'){
console.log('get in');
router.get(key,routes[key]);
}
else if(method ==='post'){
console.log('post in');
router.post(key,routes[key]);
}
}
}
return router;
}
let route12=routes=>{
console.log('calling registerroutes');
let x= _registerRoutes(routes);
return x;
}
module.exports={
route12
}
And you mentioned why you are writing the code like this It's not reliable and scalable.Yes what you said it's right.Just I tried in different way.Most of the times I would like to follow Router class to mount the different API's.Thankyou for your suggestions.and I have attached the latest code Is this ok? shall I follow this manner? correct me If i'm wrong.
app/index.js
'use strict';
const express=require('express');
const router=express.Router();
router.get('/',(req,res)=>{
res.render('login');
});
router.get('/chat',(req,res)=>{
res.render('chatroom');
});
router.get('/rooms',(req,res)=>{
res.render('rooms');
});
router.get('/info',(req,res)=>{
res.send("<h1> Information Page </h1>");
});
module.exports={
router:router
};
server.js
const express=require('express');
const app=express();
const chatcat=require('./app');
app.set('port',process.env.PORT || 8086);
app.use(express.static('public'));
app.set('view engine','ejs');
app.use('/',chatcat.router);
app.listen(app.get('port'),()=>{
console.log('server is listening on port: ',app.get('port'));
});
Upvotes: 0
Reputation: 707158
Let's take this step by step going backwards:
On this line:
app.use('/',chatcat.router);
You get an error that says chatcat.router
is undefined when it's supposed to be a function. The variable chatcat
comes from this:
const chatcat=require('./app');
So, in app/index.js, you have this:
const routes=require('./routes');
module.exports={
router: routes()
}
So, that means you're calling the function that require('./routes');
is supposed to return and putting its return value in the exports.
When, we go look in app/routes/index.js
, we see that you're exporting a function that when called returns this:
return h.route12(routes);
Where h
comes from this:
const h=require('../helpers');
When we go look in app/helpers/index.js
, we see that it's exporting the route12
function:
let route12=routes=>{
console.log('calling registerroutes');
_registerRoutes(routes);
}
module.exports={
route12
}
And, you can see that route12()
when called doesn't return anything.
Thus you end up with undefined
.
So, the quick and dirty fix is to make route12()
return a function that is whatever you want the middleware function to be.
But, honestly this code is a pretty messy. Look at how much work it was just to find out what chatcat.router
is actually supposed to be. It shouldn't be this difficult. You've put a whole bunch of intermediate files in between the top level import and the actual implementation and all those layers don't add any value. All they do is obscure things. And, since this is a middleware function, it's not like you're going to be using this same middleware function lots of other places.
There are many different ways you could clean this up, but I'd suggest putting the middleware function in its own module and require()
it in directly. If the middleware function needs access to other functionality, then let it require()
in what it needs. Modularity should generally be as shallow as possible. You shouldn't have to follow through a chain of required modules that don't add any value to get to the actual implementation.
There also appears to be a conceptual problem here. app.use()
should be used to install middleware (request handlers that participate in the handling of incoming requests). But, not only does your route12()
not return anything that could be used as middleware, that doesn't even look like it's purpose in life. When we look at _registerRoutes()
it looks like you're trying to reimplement functionality that Express already offers you, but it looks like a wrong implementation because you're assuming that it gets passed a second argument method
which your own code does not pass to it and then code inside it is attempting to put things on a router
which is never hooked up to your app.
Overall, there is likely a massively simpler way to do whatever it is you're trying to do. What exactly you're trying to accomplish isn't really described here and the implementation is enough off-base that I can't quite tell what you intended to do to know how to suggest a simplification.
Anyway, I've explained to you why you got your original error. Hopefully you can take it from there and fix/simplify.
Upvotes: 2