Why my module.exports doesn't work? - node.js

Here is my basic node.js app with only two files:
app.js
var express = require('express')
, routes = require('./routes')
, http = require('http')
, path = require('path');
var app = express();
module.exports = {
test: "test"
};
// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
// defining middlewares
app.get('/', routes.index);
http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
and my index.js:
var server = require('../app');
exports.index = function(req, res){
console.log(server);
res.send('Hello world');
};
My problem is when I go to http:\\localhost:3000 , I see in my console {} instead of {test: "test"} , it looks like the module.eports doesn't work correctly. Why ?

Requiring index.js from within app.js, and then requiring app.js from within index.js, looks like code smell to me. Additionally, if you use var app = module.exports = express() then Express is able to treat your app as middleware (so for instance, you could have a second app that requires the first app, and passes some requests to it.
When I need to access app inside another required file I do the following:
// ./routes/index.js
module.exports = function(app){
var routes = {};
routes.index = function(req, res){
console.log(app.myConfig);
res.send('Hello world');
};
return routes;
};
// ./app.js
var app = module.exports = express();
app.myConfig = {foo:'bar'};
var routes = require('./routes/index.js')(app);

You don't need to include app in index.js
indes.js should just be
exports.index = function(req, res){
console.log(server);
res.send('Hello world');
};
And I am assuming index.js is in the routes folder like so
app.js
routes
index.js

Related

Express router and routes Node.js

I get this error when I try to route my
My code
'use strict';
const express = require('express');
const app = express ();
const chatCat = require ('./app');
app.set('port', process.env.PORT || 3000);
app.use(express.static('public'));
app.set('view engine', 'ejs');
app.use('/', chatCat.router);
app.listen(app.get('port'), () => {
console.log('running on port:', app.get('port'));
});
Error
throw new TypeError('Router.use() requires a middleware function but got a ' + gettype(fn))
^
I tried routing but it keeps giving me errors from my express.js.
Try this code:
var express = require('express');
var app = express();
app.set('port', process.env.PORT || 3000);
app.use(express.static('public'));
app.set('view engine', 'ejs');
var chatCat = require('./app');
app.use('/',chatCat);
app.listen(port,function(){
console.log("Server is running on port: "+port);
});
Try creating app with this https://expressjs.com/en/starter/generator.html it will create nice structure for your project. As for your error - it needs to be express middleware function. You can't import router from your app.js as it don`t have such property. If you want to have route described here use:
app.method('/yourRoute', function(req, res, next){
//your middleware code
});
also change this:
app.listen(app.get('port'), () => {
console.log('running on port:', app.get('port'));
});
to this:
app.listen(3000);
And you can change 3000 to any unused port you want

Routing folders with express in node.js

I decided to take my routes out of my app.js and into their own seperate folders but now the site will load the handlebars file for index but not for about or contact - I am very confused and require help in exchange for a +1.
// Import the express module
var express = require('express');
var path = require("path");
var bodyParser = require("body-parser");
var index = require('./routes/index');
var about = require('./routes/about');
var contact = require('./routes/contact');
var handlebars = require('express-handlebars').create({defaultLayout:'main'});
var app = express();
// Block the header from containing information
// about the server
app.disable('x-powered-by');
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'handlebars');
app.engine('handlebars', handlebars.engine);
//set static folder
app.use(express.static(__dirname + '/public'));//allows access to public directory
//set bower folder
app.use('/bower_components', express.static(__dirname + '/bower_components'));//defines bower components directory
//body parser MW
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));
app.set('port', process.env.PORT || 1337);// Defines the port to run on
app.use("/", index);
app.use("/about", about);
app.use("/contact", contact);
app.use(function(req, res){
res.type('text/html');
res.status(404);
res.render('404');
});
app.use(function(err, req, res, next){
console.error(err.stack);
res.status(500);
res.render('500');
});
app.listen(app.get('port'), function(){
console.log("Express started on http://127.0.0.1:" + app.get('port') + ' Press Ctrl+C to terminate');
})
This is the routes/index.js file:
var express = require("express");
var router = express.Router();
// Defines the base url
router.get('/', function(req, res, next){
// Point at the home.handlebars view
res.render('home');
});
module.exports = router;
And routes/about.js
var express = require("express");
var router = express.Router();
router.get('/about', function(req, res, next){
res.render('about');
});
module.exports = router;
When I go to localhost/contact, I get my 404 page and the same for /about.
The views are located in app/views, it worked when I had them down the pipeline in the app.js but since removing them it has broken. Any suggestions would be much appreciated!
This issue was with the routing itself. Say we are looking for /about with:
app.use("/about", about);
The app will then look into the routing folder of about and find the following.
var express = require("express");
var router = express.Router();
router.get('/about', function(req, res, next){
res.render('about');
});
module.exports = router;
And since I had another /about here in the router.get this would render at localhost/about/about

Including API routes in Express 4.x

I'm learning MEAN stack with 'Getting MEAN with...' book, and problem is older Express version in books than i use.
The first step is to tell our application that we’re adding more routes to look out for,
and when it should use them. We already have a line in app.js to require the server
application routes, which we can simply duplicate and set the path to the API routes
as follows:
var routes = require('./app_server/routes/index');
var routesApi = require('./app_api/routes/index');
Next we need to tell the application when to use the routes. We currently have the following line in app.js telling the application to check the server application routes for
all incoming requests:
app.use('/', routes);
Notice the '/' as the first parameter. This enables us to specify a subset of URL s for
which the routes will apply. For example, we’ll define all of our API routes starting
with /api/ . By adding the line shown in the following code snippet we can tell the application to use the API routes only when the route starts with /api :
app.use('/', routes);
app.use('/api', routesApi);
And there's listing of my app.js file:
var express = require('express')
, others = require('./app_server/routes/others')
, locations = require('./app_server/routes/locations')
, routesApi = require('/app_api/routes/index')
, ;
require('./app_server/models/db')
var app = module.exports = express.createServer();
// Configuration
app.configure(function(){
app.set('views', __dirname + '/app_server/views');
app.set('view engine', 'jade');
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(__dirname + '/public'));
});
app.configure('development', function(){
app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});
app.configure('production', function(){
app.use(express.errorHandler());
});
// Routes
// LOCATION PAGES
app.get('/', locations.homeList);
app.get('/location', locations.locInfo);
app.get('/location/review/new', locations.addReview);
// OTHER PAGES
app.get('/about', others.about);
app.listen(3000, function(){
console.log("Express server listening on port %d in %s mode", app.address().port, app.settings.env);
});
Can someone explain me how to do the same in my Express version ?
In Express 4, this is done using Router Middleware. More info is available on Express Routing here.
A Router is simply a mini express app that you can define middleware and routes on that should all be packaged together, ie /api should all use apiRouter. Here is what apiRouter could look like
apiRouter.js
var express = require('express')
var router = express.Router(); // Create our Router Middleware
// GET / route
router.get('/', function(req, res) {
return res.status(200).send('GET /api received!');
});
// export our router middleware
module.exports = router;
Your main Express app would stay the same, so you would add your router using a require() to import the actual file, and then inject the router with use()
Express Server File
var express = require('express');
var app = express();
var apiRouter = require('../apiRouter');
var port = process.env.PORT || 3000;
app.use('/', apiRouter);
app.listen(port, function() {
console.log('listening on ' + port);
});

App is Running But Not Opening in Browser? It shows Page Not Available

In console it shows message that app/server is running but when I open app in browser it show page not available.
Here's my code for the server initialization (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 server = require('http').Server(app);
var io = require('socket.io')(server);
var app = express();
var viewRoute = require('./routes/view'),
apiRoute = require('./routes/api');
app.set('views', path.join(__dirname, 'views'));
app.engine('html', require('ejs').renderFile);
app.set('view engine', 'html');
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('/', viewRoute);
app.use('/api', apiRoute);
server.listen(9190, function(){
var host = server.address().address,
port = server.address().port;
console.log("Server Running # http:%s:%s", host, port);
});
And my file with the routes (api.js):
var express = require('express');
var api = express.Router();
module.exports = (function() {
api.get('/', function(req, res, next) {
console.log("GET Request for Index Page");
});
api.get('/home', function(req, res, next) {
console.log("GET Request for Home Page");
});
return api;
})();
I've already searched google and every other resources but can't find solution.
It seems you are not sending response back to browser,
in api.js change api.get('/' code to like following:
api.get('/', function(req, res, next) {
res.send("Yes Its working now");
});
You're not sending anything back to the client, so nothing shows up in your browser. Use res.send or similar for this.
I'd suggest to change your code for something like this, and see if this works :
var express = require('express'),
app = exports = module.exports = express();
app.get('/', function (req,res) {
console.log("GET Request for Index Page");
res.send("GET / - 200");
});
app.get('/home', function (req,res) {
console.log("GET Request for home Page");
res.send("GET /home - 200");
});
I removed the exported function immediate call by the way.
I also had same issue, My server was running but i was not able to open my app on browser, Uninstalling skype worked for me.

how do i fix routes to find views inside subfolders in node.js

i am trying to create a route for localhost:port/admin/
and i want to keep the routes.js files and view.js files in matching folders so i wont have too much spaggeti later on
but i keep getting: 500 Error: Failed to lookup view "/admin/manage_subjects"
for trying to create a new route and using same folders few the same
i have the following view folder with express
mainapp(root)
routes(folder)
admin(folder)
index.js(nested inside admin)
index.js(nested inside routes)
views(folder)
admin(folder)
admin_layout.jade(nested inside admin)
manage_subjects.jade(nested inside admin)
index.jade(nested inside views)
layout.jade(nested inside views)
code:
routes/admin/index.js
exports.index = function (req, res) {
res.render('manage_subjects',{title:'Express'});}
views/admin/manage_subjects.jade
extends admin_layout
block content
h1 = title
p Welcome to #{title}
my app.js code
/**
* Module dependencies.
*/
var express = require('express')
, routes = require('./routes')
, admin_routes = require('./routes/admin/')
, user = require('./routes/user')
, http = require('http')
, path = require('path')
, repository = new (require('./domain_model/repository'))();
var app = express();
// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
// development only
if ('development' == app.get('env')) {
app.use(express.errorHandler());
}
//fill local subjects
repository.subjects.GetAll(function (err, data) {
if (err) throw err;
app.locals.subjects = data;
});
//append routes
app.get('/', routes.index);
app.get('/admin', admin_routes.index);
app.get('/users', user.list);
http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on http://localhost:' + app.get('port'));
});
I've been dealing with what I think is the same problem and figured out how to fix it. So in case someone else comes across this problem I'm posting my solution.
So here is what I had that was causing 404's and 500's
app.js
var routes = require('./routes/index');
var admin = require('./routes/admin');
app.use('/', routes);
app.use('/admin', admin);
and here was my routes/index.js
//append routes
var express = require('express');
var router = express.Router();
router.get('/', function(req, res) {
res.render('index', {title: 'Express'});
});
module.exports = router;
and my routes/admin.js:
var express = require('express');
var router = express.Router();
router.get('/admin', function(req, res) {
res.render('admin/index', {title: 'Express'});
});
module.exports = router;
by defining the second /admin inside the router.get() function I think I was effectively telling node to look for the html in my views folder under the following path views/admin/admin/index.ejs. So to fix that all I had to do was remove either the /admin from the router.get() or the /admin from the app.use()
So my working code now looks like this:
app.js
var routes = require('./routes/index');
var admin = require('./routes/admin');
app.use('/', routes);
app.use('/admin', admin); //I left the /admin here and instead removed the one in routes/admin.js
and here was my routes/index.js
//append routes
var express = require('express');
var router = express.Router();
router.get('/', function(req, res) {
res.render('index', {title: 'Express'});
});
module.exports = router;
and my routes/admin.js:
var express = require('express');
var router = express.Router();
router.get('/', function(req, res) { //NOTICE THE CHANGE HERE
res.render('admin/index', {title: 'Express'});
});
module.exports = router;
So making that change made it so I could have sub folders in my views folder.
Simple Answer for sub-folders inside the views folder (mine is called frontend)
click here the picture to see the folder structure
file app.js
app.set('views', [path.join(__dirname, 'frontend'), path.join(__dirname, 'frontend/locked'), path.join(__dirname, 'frontend/template'), path.join(__dirname, 'frontend/public')]);
app.set('view engine', 'pug')
I'd check out TJ's video on Modular apps on his vimeo the best part about this work flow is your code becomes really flexible and it's alot easier to stay DRY.
Additionally I would do something like this with my app.set("views")
var path = require("path");
app.set('views', path.join(__dirname, 'views'));
// you can then extend this to the example for routes
Another alternative would be something like in your app.js file:
var express require("express")
var app = express()
var routes = require("./path/to/routes")(app)
and then routes would look like:
routes = function (app) {
app.get("/route", middleWareifYou.gotIt, route.handler || function (req, res) {
res.send("some msg");
});
};
module.exports = routes
Cheers, I hope this helps!
I had a similar problem and what worked for me was setting the views folder in both the main app file and in the router file too.
So in the main app.js file I had:
app.set('views', viewsFolderPath);
And inside my router.js file I also did the same thing:
app.set('views', viewsFolderPath);

Resources