I am playing with node.js and I don't quite understand why something I set up is working in one instance but if I make a slight change it will not work in another instance.
in my app.js I have
app.use('/musicplayer', require('./routes/music/index'));
in my music\index.js I have
var express = require('express');
var router = express.Router();
router.use('/users', require('./users'));
module.exports = router;
in my users.js I have this - working version
var express = require('express');
var usersRouter = express.Router();
var sqllite3 = require('sqlite3').verbose();
usersRouter.get('/login', function(req, res, next) {
res.render('music/login', { title: 'Express' });
});
module.exports = usersRouter;
But I would like to encapsulate the routes I am defining into another function like this not working this just hangs the page.
Modified version of my users.js not working
var express = require('express');
var usersRouter = express.Router();
var sqllite3 = require('sqlite3').verbose();
var router = function () {
usersRouter.get('/login', function (req, res, next) {
res.render('music/login', {title: 'Express'});
});
return usersRouter;
}
module.exports = router;
In the console I can see it comes in tries the get and nevers gets routed I see this "GET /musicplayer/users/login - - ms - -".
I have even put a console.log right before the return in the anonymous function I created to know it is getting in there and that I am hooking the pathways up right from the parent routes. And I do hit that log action to the screen.
Any help or tips would be appreciated:)
PS in case you are wondering I am trying to separate out apps for different development work I want to play with. So that is why I am doing the sub routing with musicplayer/index.js instead of just putting everything in the app.js for declaring of my main routes.
Router.use() expects an instance of another Router. However your (non-working) module only returns a function.
Use this in your index.js to fix the issue:
router.use('/users', require('./users')());
Related
Keep getting this error, whilst trying to run my app. Low level of knowledge have tried many solutions online to fix this, but nothing has got me up and running. Here is the Error-
Error: Route.get() requires a callback function but got a [object Undefined]
at Route.(anonymous function) [as get] (d:\dev_portal\bit_racer_real\alpha_bit_racer\node_modules\express\lib\router\route.js:202:15)
index.js
var express = require('express');
var router = express.Router();
router.get('/', function(req, res) {
res.redirect('/catalog');
});
module.exports = router;
catalog.js
var express = require('express');
var router = express.Router();
// Require controller modules.
var horse_controller = require('../controllers/horseController');
router.get('/', horse_controller.index);
module.exports = router;
app.js
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var catalogRouter = require('./routes/catalog');
var app = express();
var mongoose = require('mongoose');
var mongoDB = 'mongodb://admin:bitracer33#ds123753.mlab.com:23753/alpha_bit_racer';
mongoose.connect(mongoDB);
mongoose.Promise = global.Promise;
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'MongoDB connection error:'));
app.use('/', indexRouter);
app.use('/users', usersRouter);
app.use('/catalog', catalogRouter);
module.exports = app;
Not exactly sure where I have gone wrong, I have also heard that I may have a call in my routes index.js file in express. The call doesn't exist. I have spent hours going over the code making small changes, trying to get this simple error to clear :(
Has anyone else experienced this problem. Id love to get a clear answer.
as far as I can see, your index.js file is in the horsecontroller directory.
But when you use CommonJS's require with a directory instead of a file, it automatically defaults that to ../path/to/directory/index.js, so you don't have to specify horse_controller.index in the app.get function, instead just specify horse_controller.
The final code would look like this:
var express = require('express');
var router = express.Router();
// Require controller modules.
var horse_controller = require('../controllers/horseController');
router.get('/', horse_controller);
module.exports = router;
Like Daksh said, in the line router.get('/', horse_controller.index); (file catalog.js) horse_controller.index is not a function.
In your catalog.js you require your controller lke this require('../controllers/horseController') that means you have horseController.js file or horseController is a directory and in which you have an index.js file. After requiring it you save it in horse_controller variable and when you register It as an request handler you specify horse_controller.index
This presume you have exporting in your horseController an object like this
module.export = {
index: function(request, response) {
// Your code goes here
}
}
but if it isn't the case that why your are getting that error
Error: Route.get() requires a callback function but got a [object Undefined]
This code means you have heighter you are exporting nothing in your ../controllers/horseController file or ../controllers/horseController/index.js
If the index.js file under the horseController directory you can pass the horse_controller variable directly as an request handler to the app.get like this
app.get('/', horse_controller);
Passing it directly because in the index.js file you are exporting the Express Router directly
I got this resolved.
I was missing .index function from controller .js file.
added this line
exports.index = function(req, res) {
res.send('NOT IMPLEMENTED: Site Home Page');
};
now .index is no longer looking for an object.
Thanks for the help, appreciate the responses. :)
I have used the express generator plugin and I had all my routes generated on routes/index.js but I'm doing a refactor now and I'm putting all of the routes in it's respective router files. The thing is that the 'pg' module works fine if I put my code on the index.js :
index.js
var express = require('express');
var router = express.Router();
var pg = require('pg');
var connectionString = 'postgres://postgres:postgres#localhost:5432/dataDB';
router.use('/api/events', require('./events'))
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', { title: 'Express' });
});
module.exports = router;
Now if I request a route from the routes/events.js file I get a 'pg'(postgres driver) not defined
var express = require('express');
var router = express.Router();
var pg = require('pg');
var connectionString = 'postgres://postgres:postgres#localhost:5432/dataDB';
//get all events from a user
router.get('/user/id/:id_user', function(req, res) {
.....
});
router.post('/friends/', function(req, res) {
........
});
module.exports = router
And the app.js only includes the router/index.js file ......How can I solve this?. The requests are getting to the router/events.js file correctly, but it's just not recognizing the 'pg' module require......Thank you very much
The problem was that I was including
var pg = require('pg');
in both routes/index.js and in routes/events.js
I removed that line from the index.js and left it only in event.js and now it works perfectly. That require is going in the model layer anyway, but now that I fixed it I would like to know why requiring something on one script and then requiring something on another script fails on express given the fact that I included express and the router in both files and those 2 lines didn't fail but the mentioned line did......
I'm making a nodeJS module, and I want to use expressJS as a framework for it.
I'm trying to see, how I could go by, including a function inside and app.get(); and call it via another file, such as the actual app.
var express = require("express");
var app = express();
app.get("/", function (req, res) {
exports.type = function (text) {
console.log(req.ip);
console.log(text);
}
});
now when I use this, and i call it on the actual app like:
var web = require("directory_to_file");
var express = require("express");
var app = express();
var http = require("http").Server(app);
app.get("/", function (req, res) {
web.type("Hello, world");
});
http.listen(10022, function () {
console.log("server is up");
});
I get an error:
TypeError: Property 'type' of object #<Object> is not a function
anyone know a way to make it so I can call the function?
There are generally two things you want to export as a module - an API and a Middleware. The classic example of middleware is an authentication module. To do the middleware, just export the middleware. I tend to do a little more than that so I can configure the middleware later. Something along the lines of this:
module.exports = exports = function(config) {
// Do something with config here
return function(req, res, next) {
// your middleware here
};
};
You can then use your middleware in your main program like this:
var app = require('express')(),
mymodule = require('./mymodule');
var config = {}; // replace with whatever config you need
app.use(mymodule(config));
app.listen(process.env.PORT || 3000);
To implement an API, you will create a Router object, then attach your routes to the Router object. You can then "mount" your router in your main program. For example, you could have a file called 'myroutes.js' with the following contents:
var express = require('express'),
myroutes = express.Router();
myroutes.get('/foo', (req, res) => {
res.status(200).type('application/json').send({ myparam: 'foo' });
});
module.exports = exports = myroutes;
Have the following in your main program:
var app = require('express')(),
myroutes = require('./myroutes');
app.use('/api', require('./myroutes'));
app.listen(process.env.PORT || 3000);
Here, in 'myroutes.js', I'm defining a sub-route of /foo and then in the main program, I'm mounting that on /api - so I would access /api/foo to access that API.
In your directory_to_file you are only exporting on app.get('/') which will never be called.
You could add in your directory_to_file the following code
var express = require('express');
var router = express.Router();
router.get('/', function(req, server) {
console.log(req.ip);
});
module.exports = router;
And in your main file you could use app.use('/', web)
A short explanation:
You are creating a new express app / config in your directory_to_file file which won't be launched or used. So your app.get event won't be fired once.
That's why web.type is not a function. You are not exporting anything.
Use the way I provided. This is a commonly used method.
You could call the code I provided a "route". Create multiple routes / route files and include them in your main method.
Your code just looks confused. If I understand you correctly, what you are really trying to do (at least in Node/express terminology) is write your own middleware.
Express is designed with this in mind and it's pretty straightforward e.g.
ipLogger.js
module.exports = function(req, res, next) {
console.log(req.ip);
next();
}
app.js
var http = require("http")
, express = require("express");
, app = express()
, server = http.Server(app)
, ipLogger = require("./ipLogger.js");
app.use(ipLogger()); // log IP of all requests
// handle routes
server.listen(10022, function() {
console.log("server is up");
});
Dumb/Newb question...
I am learning/working on an API in Node / Express4 and I would like to break my routes out into another module. I have it working with the following code, but it seems awkward to me to keep re-using the require('express') statement... Is there a way to move more of the code from the routes.js file into server.js and still keep my .get and .post statements in the routes module? Thanks in advance!
server.js:
'use strict';
var express = require('express');
var routes = require('./routes');
var app = express();
app.use('/api', routes);
app.listen(3000, function() {
console.log('Listening);
});
routes.js
var express = require('express'); // how do I get rid of this line?
var router = express.Router(); // can I move this to server.js?
var apiRoute = router.route('');
apiRoute.get(function (req, res) {
res.send('api GET request received');
});
module.exports = router;
Your on the right track. Its actually cool to reuse the var express = require('express'); statement each time you need it. Importing, ( requiring ), modules is a cornerstone of modular development and allows you to maintain a separation of concerns with in the files of your project.
As far as modularly adding routes is concerned: The issue is that routes.js is misleading.
In order to modularly separate out your routes you should use several modules named <yourResource>.js. Those modules would contain all of the routing code as well as any other configuration or necessary functions. Then you would attach them in app.js with:
var apiRoute = router.route('/api');
apiRoute.use('/<yourResource', yourResourceRouter);
For example, if you had a resource bikes:
In app.js or even a module api.js:
var apiRoute = router.route('/api')
, bikeRoutes = require('./bikes');
apiRoute.use('/bikes', bikeRoutes);
Then in bike.js:
var express = require('express');
var router = express.Router();
var bikeRoutes = router.route('/');
bikeRoutes.get(function (req, res) {
res.send('api GET request received');
});
module.exports = bikeRoutes;
From there its easy to see that you can build many different resources and continually nest them.
I'm building a web app with Express and Node and am trying to factor my routing so that I don't have hundreds of routes in the same file. This site serves different files within the projects directory, so I made a file in routes/ called projectRoutes.jsto handle the routing for project files:
var express = require('express');
module.exports = function() {
var functions = {}
functions.routeProject = function(req, res) {
res.render('pages/projects/' + req.params.string, function(err, html) {
if (err) {
res.send("Sorry! Page not found!");
} else {
res.send(html);
}
});
};
return functions;
}
Then, in my routes.js, I have this...
var projectRoutes = require("./projectRoutes");
router.get('/projects/:string', function(req, res) {
projectRoutes().routeProject(req, res);
});
Is there a better way to structure this functionality within projectRoutes.js? In other words, how can I configure projectRoutes.js so that I can write the follow line of code in index.js:
router.get('/projects/:string', projectRoutes.routeProject);
The above seems like the normal way to handle something like this, but currently the above line throws an error in Node that says the function is undefined.
Thanks for your help!
You should use the native express router, it was made to solve this exact problem! It essentially lets you create simplified nested routes in a modular way.
For each of your resources, you should separate out your routes into several modules named <yourResource>.js. Those modules would contain all of the routing code as well as any other configuration or necessary functions. Then you would attach them in index.js with:
var apiRoute = router.route('/api')
apiRoute.use('/< yourResource >', yourResourceRouter)
For example, if you had a resource bikes:
In index.js:
var apiRoute = router.route('/api')
, bikeRoutes = require('./bikes')
apiRoute.use('/bikes', bikeRoutes)
Then in bike.js:
var express = require('express')
, router = express.Router()
, bikeRoutes = router.route('/')
bikeRoutes.get(function (req, res) {
res.send('api GET request received')
});
module.exports = bikeRoutes
From there its easy to see that you can build many different resources and continually nest them.
A larger of example of connecting the routes in index.js would be:
var apiRoute = router.route('/api')
, bikeRoutes = require('./bikes')
, carRoutes = require('./cars')
, skateboardRoutes = require('./skateboards')
, rollerskateRoutes = require('./rollerskates')
// routes
apiRoute.use('/bikes', bikeRoutes)
apiRoute.use('/cars', carRoutes)
apiRoute.use('/skateboards', skateboardRoutes)
apiRoute.use('/rollerskates', rollerskateRoutes)
Each router would contain code similar to bikes.js. With this example its easy to see using express's router modularizes and makes your code base more manageable.
Another option is to use the Router object itself, instead of the Route object.
In Index.js:
//Load Routes
BikeRoutes = require('./routes/Bike.js');
CarRoutes = require('./routes/Car.js');
//Routers
var express = require('express');
var ApiRouter = express.Router();
var BikeRouter = express.Router();
var CarRouter = express.Router();
//Express App
var app = express();
//App Routes
ApiRouter.get('/Api', function(req, res){...});
ApiRouter.use('/', BikeRouter);
ApiRouter.use('/', CarRouter);
In Bike.js:
var express = require('express');
var router = express.Router();
router.get('/Bikes', function(req, res){...});
module.exports = router;
Similarly in Car.js