Reputation: 2954
folks.
I am doing just a very simple API (localhost development), and I am curious why the last route is never got by ExpressJS server.
Here are the routes:
var express = require('express');
var bodyParser = require('body-parser');
var router = express();
// (...) other variables defined here...
router.all('*', function(req, res, next) {
res.header('Access-Control-Allow-Origin', 'localhost');
res.header('Access-Control-Allow-Methods', 'PUT, GET, POST, DELETE, OPTIONS');
res.header('Access-Control-Allow-Headers', 'Content-Type');
next();
});
// Works great!
router.get('/', function(req, res) {
res.render('index');
});
// Works great!
router.get('/api/states', function(req, res) {
res.json(states);
});
// Works great!
router.get('/api/cities/:state', function(req, res, state) {
res.json(cities);
});
// Never Works!!
router.get('/api/stores/:state/:city', function(req, res, state, city) {
res.json('{"result": true}');
});
router.use(express.static(__dirname + '/../../www'));
router.set('views', __dirname + '/../../www');
router.engine('html', require('ejs').renderFile);
router.set('view engine', 'html');
router.listen(process.env.PORT || 9000);
From my app I call these URLs to the last route:
http://localhost/api/stores/sp/city_name
It is always 404.
I simply can not realise why this is 404. The last route, witch never worked, is basically a copy from the previous route (that works great).
Could someone point what I am doing wrong here?
ps: the last route should accept a third optional parameter. I also had tried this:
// Never Works!!
router.get('/api/stores/:state/:city/*?', function(req, res, state, city) {
res.json('{"result": true}');
});
But, if I can not do it work with two defined parameters, it will not work with extra optional parameters, right?
Any advice is very appreciate.
Thank you.
Upvotes: 1
Views: 829
Reputation: 2214
You have too many arguments in your handler--function handlers that take four arguments are reserved for error handling, i.e. only called when somewhere in the middleware chain next(error)
was called, or a exception was caught. Read the docs for further info.
// Remove `state` and `city` arguments, access via `req.params.*`
router.get('/api/stores/:state/:city', function(req, res) {
var state = req.params.state
var city = req.params.city
res.json('{"result": true}');
});
The reason you are not getting a 404 for the other handler is because you're accepting three arguments. So I should point out the state
argument will not be what you expect, it will be a function to invoke the next middleware, commonly named next
.
// NOPE! function (req, res, state)
router.get('/api/cities/:state', function(req, res) {
var state = req.params.state
res.json(cities);
});
// Common middleware handler, third parameter is a function that when invoked will call the next middleware
router.get('/some/uri', function (req, res, next) {
doSomethingAsync()
.then(data => {
req.data = data
next()
})
.catch(err => next(err))
})
Upvotes: 1