I'm new to express and used yo-generator to create my project. The problem I'm facing is that routes with:
app.get('/something') are working fine, but
router.get('/something') are not working. I tried to research but could not solve the problem.
Here are my files:
app.js
var fs = require('fs');
var http = require('http');
var path = require('path');
var helmet = require('helmet');
var express = require('express');
var root = path.normalize(__dirname + '/');
var constant = require(root + '/app/util/constants.js');
var config = require(constant.APP_CONFIG_FILE);
var app = express();
app.use(helmet());
app.use(function(req, res, next) {
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader("Access-Control-Allow-Headers", "DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type");
return next();
});
require('./config/express')(app, config);
http.createServer(app).listen(config.WEB_PORT, function() {
console.log('Server listening http on port ' + config.WEB_PORT);
});
module.exports = app;
Lines from express.js
var env = process.env.NODE_ENV || 'development';
app.locals.ENV = env;
app.locals.ENV_DEVELOPMENT = env == 'development';
app.set('views', config.ROOT + '/app/views');
app.set('view engine', 'ejs');
// app.use(favicon(config.root + '/public/img/favicon.ico'));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(cookieParser());
app.use(compress());
app.use(express.static(config.ROOT + '/public'));
app.use(methodOverride());
var controllers = glob.sync(config.ROOT + '/app/controllers/*.js');
controllers.forEach(function(controller) {
require(controller)(app);
});
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
app/controllers/user-ctrl.js
var path = require('path');
var express = require('express');
var router = express.Router();
var root = path.normalize(__dirname + '/../..');
var constant = require(root + '/app/util/constants.js');
var service = require(constant.USER_SERVICE_FILE);
var responseUtil = require(constant.RESPONSE_UTIL_FILE);
module.exports = function(app) {
app.use(constant.USER_PATH, router); // constant.USER_PATH is '/user' (added after alexmac asked)
**// this works**
app.get('/test', function(req, res) {
res.write('hello');
res.end();
});
**// This doesn't work**
router.get('/test', function(req, res) {
res.write('hello');
res.end();
});
};
/*
GET: /user
*/
router.route('/:page?/limit?/:limit')
.get(function(req, res) {
responseUtil.sendResponse(service.allRecords(req, res), req, res);
});
/*
POST: /user
*/
router.route('/')
.post(function(req, res) {
responseUtil.sendResponse(service.saveRecord(req, res), req, res);
});
/*
GET: /user/1
PUT: /user/1
DELETE: /user/1
*/
router.route('/:id')
.get(function(req, res) {
responseUtil.sendResponse(service.findRecord(req, res), req, res);
})
.delete(function(req, res) {
responseUtil.sendResponse(service.deleteRecord(req, res), req, res);
})
.put(function(req, res) {
responseUtil.sendResponse(service.updateRecord(req, res), req, res);
});
These are the key lines. I've changed the order to try to clarify the intent but that shouldn't change how they behave:
// Create a route for GET /test
app.get('/test', function(req, res) {
res.write('hello');
res.end();
});
// Create a route for GET /user/test
router.get('/test', function(req, res) {
res.write('hello');
res.end();
});
app.use('/user', router);
The router is mounted at the path /user so any paths on the router will be relative to /user. In other words, if app is handling requests at http://localhost/test then router will handle http://localhost/user/test.
Change your code with this piece of code
var express = require('express');
var bodyParser = require('body-parser');
var router = express.Router();
router.use(bodyParser.json());
var app = express();
router.get('/test', function(req, res) {
res.write('hello');
res.end();
});
app.use('/route',router);
module.exports = router;
When you want to get use http://localhost:port/route/test
Hope this helps.
Related
I have created a Node.JS REST API server, and tried to test it by sending a GET request on https://localhost:3443/public/images/logo.png that logo.png image exist and I can see it in the directory. But the Postman gives me Not Found 404 error message.
This is my imagesRouter.js:
const express = require('express');
const bodyParser = require('body-parser');
const Images = require('../models/images');
var authenticate = require('../authenticate');
const imagesRouter = express.Router();
const cors = require('./cors');
imagesRouter.use(bodyParser.json());
imagesRouter.options('*', cors.corsWithOptions, (req, res) => { res.sendStatus(200); } );
imagesRouter.route('/')
//.options(cors.corsWithOptions, (req, res) => { res.sendStatus(200); })
.get(cors.cors, (req,res,next) => {
Images.find({})
.then((images) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'application/json');
res.json(images);
}, (err) => next(err))
.catch((err) => next(err));
})
module.exports = imagesRouter;
And this is my app.js file:
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 index = require('./routes/index');
var usersRouter = require('./routes/usersRouter');
var imagesRouter = require('./routes/imagesRouter');
const uploadRouter = require('./routes/uploadRouter');
const Images = require('./models/images');
//const uploadRouter = require('./routes/uploadRouter');
//const favoriteRouter = require('./routes/favoriteRouter')
var config = require('./config');
const mongoose = require('mongoose');
//mongoose.set('useCreateIndex', true);
mongoose.Promise = require('bluebird');
var passport = require('passport');
var authenticate = require('./authenticate');
// Connection URL
const url = config.mongoUrl;
const connect = mongoose.connect(url, {
//useMongoClient: true,
/* other options */
useNewUrlParser: true ,
useUnifiedTopology: true
});
connect.then((db) => {
console.log("Connected correctly to server");
}, (err) => { console.log(err); });
var app = express();
// Secure traffic only
app.all('*', (req, res, next) => {
if (req.secure) {
return next();
}
else {
res.redirect(307, 'https://' + req.hostname + ':' + app.get('secPort') + req.url);
}
});
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
// uncomment after placing your favicon in /public
//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(passport.initialize());
app.use('/', index);
app.use('/users', usersRouter);
app.use(express.static(path.join(__dirname, 'public')));
app.use('/public/images',imagesRouter);
app.use('/imageUpload',uploadRouter);
//app.use('/imageUpload',uploadRouter);
//app.use('/favorites',favoriteRouter);
// 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) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
EDIT: This is my app files tree:
You'll need to specify the base of the static router to point to the public folder. You are currently "mounting" the public folder on the root route in the current code. You can change this line
app.use(express.static(path.join(__dirname, 'public')));
To:
app.use('/public', express.static(path.join(__dirname, 'public')));
Alternatively, you can call the endpoint from postman (or any other client) as: https://localhost:3443/images/logo.png
I am new to NodeJs and Express. I want to make an Ajax call from an ejs file :
<script>
$(document).ready(function() {
$.ajax({
async : false,
url: "/organisation/list",
success : function(data, status, xhr) {
alert("finsihed");
}
});
});
</script>
Here is the config of my app :
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var indexRouter = require('./routes/index');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', indexRouter);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
Here is the index.js file :
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', { title: 'Express' });
});
module.exports = router;
How to make it possible to reach the Ajax url /organisation/list ? Should I create another file in the routes directory ?
You can simply write a route like this :
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', { title: 'Express' });
});
/* GET organisation list. */
router.get('/organisation/list', function(req, res, next) {
res.render('index', { title: 'Express' });
});
module.exports = router;
or you can create a separate file that handles all requests related to the organization.
app.js
app.use('/organization', require('./routes/organization.js');
routes/organization.js
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/list', function(req, res, next) {
//res.render('index', { title: 'Express' });
res.status(200).json([]);
});
module.exports = router;
In my server.js file I have below url mappings:
app.use('/registerCourse', require('./controllers/training.controller'));
app.use('/getCourses', require('./controllers/training.controller'));
In training.controller file I have mapped below way:
router.post('/registerCourse', registerCourse);
router.get('/getCourses', getCourses);
when call "/registerCourse","/getCourses","/getCourseDetails" throwing error saying:
"Cannot GET /getCourses"
Server.js -
require('rootpath')();
var express = require('express');
var app = express();
var session = require('express-session');
var bodyParser = require('body-parser');
var expressJwt = require('express-jwt');
var config = require('config.json');
app.set('view engine', 'ejs');
app.set('views', __dirname + '/views');
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(session({ secret: config.secret, resave: false, saveUninitialized: true }));
app.use('/login', require('./controllers/login.controller'));
app.use('/app', require('./controllers/app.controller'));
app.use('/registerCourse', require('./controllers/training.controller'));
app.use('/getCourses', require('./controllers/training.controller'));
app.use('/getCourseDetails', require('./controllers/training.controller'));
app.get('/', function (req, res) {
return res.redirect('/app');
});
var server = app.listen(3000, function () {
console.log('Server listening at http://' + server.address().address + ':' + server.address().port);
});
training.controller.js-
var config = require('config.json');
var express = require('express');
var app = express();
var router = express.Router();
var trainingService = require('services/training.service');
app.use(router);
router.post('/registerCourse', registerCourse);
router.get('/getCourses', getCourses);
router.get('/getCourseDetails', getCourseDetails);
module.exports = router;
function registerCourse(req, res) {
console.log(" registerCourse called ()"+req.body);
trainingService.register(req.body);
}
function getCourses(req, res) {
trainingService.getCourses()
.then(function (data) {
res.json(data);
})
.catch(function (err) {
res.status(400).send(err);
});
}
function getCourseDetails(req, res) {
console.log(req.body)
}
Solution:
Your route will be:
/registerCourse
/getCourses
/getCourseDetails
app.js
app.use('/login', require('./controllers/login.controller'));
app.use('/app', require('./controllers/app.controller'));
app.use('/',require('./controllers/training.controller'));
/*
app.use('/registerCourse', require('./controllers/training.controller'));
app.use('/getCourses', require('./controllers/training.controller'));
app.use('/getCourseDetails', require('./controllers/training.controller'));
-- removed
*/
training.controller.js
var config = require('config.json');
var express = require('express');
// var app = express(); -- removed
var router = express.Router();
var trainingService = require('services/training.service');
// app.use(router); -- removed
router.post('/registerCourse', registerCourse);
router.get('/getCourses', getCourses);
router.get('/getCourseDetails', getCourseDetails);
module.exports = router;
function registerCourse(req, res) {
console.log(" registerCourse called ()"+req.body);
trainingService.register(req.body);
}
function getCourses(req, res) {
trainingService.getCourses()
.then(function (data) {
res.json(data);
})
.catch(function (err) {
res.status(400).send(err);
});
}
function getCourseDetails(req, res) {
console.log(req.body)
}
In server.js you can use
app.use('/', require('./controllers/training.controller'));
app.use('/', require('./controllers/training.controller'));
app.use('/', require('./controllers/training.controller'));
and then try calling your
"/registerCourse","/getCourses","/getCourseDetails"
I'm just starting out and I've got a barebones app here with a routes file ./routes/index.js.
When I browse to http://localhost:3000/index for example index.js is hit but none of the routes match and the program just goes straight through to "return router;". If I browse to http://localhost:3000/ I get the same again.
All the browser does is think about it for a bit and then give me a ERR_CONNECTION_RESET.
app.js
var express = require('express');
var logger = require('morgan');
var bodyParser = require('body-parser');
var mongoose = require('mongoose');
var flash = require('connect-flash');
mongoose.connect('mongodb://localhost/blah');
var app = express();
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(flash());
app.use(require('./routes/index'));
module.exports = app;
index.js
var express = require('express');
var router = express.Router();
function authorize(req, res, next) {
if (true) {
next()
} else {
res.status(403).send('Forbidden')
}
}
module.exports = function(){
router.get('/index', function(req, res) {
res.send('index');
});
router.get('/hello/:name', function(req, res) {
res.send('hello ' + req.params.name + '!');
});
router.get('/', function(req, res) {
res.send('root');
});
return router;
}
app.js is missing a line to actually start the server. You need to add this:
app.listen(3000);
Got there in the end... I changed
module.exports = function(){
router.get('/index', function(req, res) {
res.send('index');
});
router.get('/hello/:name', function(req, res) {
res.send('hello ' + req.params.name + '!');
});
router.get('/', function(req, res) {
res.send('root');
});
return router;
}
to
router.get('/index', function(req, res) {
res.send('index');
});
router.get('/hello/:name', function(req, res) {
res.send('hello ' + req.params.name + '!');
});
router.get('/', function(req, res) {
res.send('root');
});
module.exports = router;
I am following Practical Node.js book. It is based on older version on express.js. The book is trying to build a blog. It has several different routes files. Ex- index.js, admin.js, article.js etc. This route classes are called from app.js. Ex:
app.use('/', routes.index);//// THE ISSUE IS HERE /////
app.get('/login', routes.user.login);
app.post('/login', routes.user.authenticate);
app.get('/logout', routes.user.logout);
app.get('/admin', routes.article.admin);
app.get('/post', routes.article.post);
app.post('/post', routes.article.postArticle);
Whenever someone tries to access '/', I am setting a collections object of artices and users in the request object.
var dbarticles = require('./db/articles.json');
var dbusers = require('./db/users.json');
app.use(function(req, res,next) {
if (!collections.articles || ! collections.users) return next(new Error("No collections."))
req.collections = collections;
return next();
});
app.use('/', routes.index);//// THE ISSUE IS HERE /////
The problem is that in index.js file, the value of req.collections is no available, I get 'undefined'. What am I missing. I have checked in the console.log, that the value is present in req.collections before the '/', route.index is hit.
Here's my app.js
var express = require('express');
var router = express.Router();
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var session = require('express-session');
var methodOverride = require('method-override');
var routes = require('./routes');
var dbarticles = require('./db/articles.json');
var dbusers = require('./db/users.json');
var collections = {
articles: dbarticles,
users: dbusers
};
var logger = require('morgan');
var errorHandler = require('errorhandler');
var app = express();
app.locals.appTitle = 'blog-express';
//console.log(collections.articles || collections.users);
app.use(function(req, res,next) {
if (!collections.articles || ! collections.users) return next(new Error("No collections."))
req.collections = collections;
return next();
});
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
// uncomment after placing your favicon in /public
//app.use(favicon(__dirname + '/public/favicon.ico'));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded());
app.use(methodOverride());
app.use(require('stylus').middleware(__dirname + '/public'));
app.use(express.static(path.join(__dirname, 'public')));
// Pages and routes
app.use('/', routes.index);
app.get('/login', routes.user.login);
app.post('/login', routes.user.authenticate);
app.get('/logout', routes.user.logout);
app.get('/admin', routes.article.admin);
app.get('/post', routes.article.post);
app.post('/post', routes.article.postArticle);
app.get('/articles/:slug', routes.article.show);
// REST API routes
app.get('/api/articles', routes.article.list);
app.post('/api/articles', routes.article.add);
app.put('/api/articles/:id', routes.article.edit);
app.delete('/api/articles/:id', routes.article.del);
app.all('*', function(req, res) {
res.sendStatus(404);
})
// catch 404 and forward to error handler
// error handlers
// development error handler
// development only
if ('development' == app.get('env')) {
app.use(errorHandler());
}
// production error handler
// no stacktraces leaked to user
//module.exports = router;
module.exports = app;
Here is my index.js
exports.article = require('./article');
exports.user = require('./user');
/*
* GET home page.
*/
exports.index = function(req, res, next){
console.log(".." + res.collections);
req.collections.articles.find({published: true}, {sort: {_id:-1}}).toArray(function(error, articles){
if (error) return next(error);
res.render('index', { articles: articles});
})
};
If some one needs to take a look at the code base of book, please check this github url - https://github.com/azat-co/practicalnode/tree/master/ch5/blog-express
Try changing app.use('/', routes.index) to app.get('/',routes.index)
If that doesn't work, try setting the middleware inline...
var setCollections = function (req, res,next) {
if (!collections.articles || ! collections.users) return next(new Error("No collections."))
req.collections = collections;
return next();
}
app.get('/', setCollections, routes.index)