Function isn't being called in Node Js using REST API - node.js

I am writing a code in Node JS, which uses mustache for templating html and REST API as backend.
Here is my code that doesn't work.
function setupRoutes(app) {
const base = app.locals.base;
app.get(`${base}/search.html`,doSearchContent(app));
app.get(`${base}/:name`,doGetContent(app));
}
function doSearchContent(app) {
return async function(req, res) {
console.log("here");
}; };
When I run my program and go to base/search.html. It never calls the doSearchContent method.
Any idea why and how I can fix this?
EDIT: The doGetContent works as expected. It's when I run the search.html it doesn't

The express paths should be started with a leading slash. Please change your routes addition to something like this:
...
app.get(`/${base}/search.html`,doSearchContent(app));
app.get(`/${base}/:name`,doGetContent(app));
...
Express matches the path of http request against the 'path' provided for all routes to decide which routes must be called. Since the http paths always start with a slash, your routes also must specify those to match.

These lines
app.get(`${base}/search.html`,doSearchContent(app));
app.get(`${base}/:name`,doGetContent(app));
are not working as you expect. In Express routes we don't invoke functions directly. Instead, we either pass a name of a callback fucntion to invoke, that receives req and res params, or an anonymous callback. In your case it could be something like this:
app.get(`${base}/search.html`,(req, res) => {
console.log("It's alive!");
doSearchContent(app);
});
app.get(`${base}/:name`, (req, res) => {
doGetContent(app)
});
The express paths should be started with a leading slash.
This is not true

Have you added search.html file or used a template to build the HTML?
Make sure the template is being called and not the html file.
Other than that your code looks fine and it should work

Related

Some Express.Router() routes do not execute middleware function

I'm trying to wrap my head around my implementation of express.router() not triggering of the middleware function assigned to it.
I wrote a pretty big app and trying to add a few more endpoints to my path, but for some reason the 9th route gets loaded but does not trigger the function.
app.js
server.use(cors());
server.use(function (req, res, next) {
next();
});
server.use("/", express.static("./assets"));
server.use("/api", api);
server.use("/debug", debug);
server.use("/config", config);
server.use("/control", control);
server.use("/tools", files);
And this is where I declared my routes with the respective functions.
router.get("/teams", onGetTeams);
router.get("/players", onGetPlayers);
router.get("/achievements", getTop3);
router.get("/xpression", onXprPayload);
router.get("/snapshot", onRequestSnapshot);
router.get("/round-timeline", onRequestTimelinePayload);
router.get("/:half", onRequestHalf);
router.get("/dashboard-message", onSetDashboardMessage);
router.get("/get-match-odds", getTeamOdds);
function getTeamOdds(req, res) {
console.log("Sent odds");
res.json(odds);
res.end();
}
When I make the request for the last route, the function does not get executed, and I get back a 200 response.
Is there something big I'm missing?
Thank you !
Your route definition here:
router.get("/:half", onRequestHalf);
is a wildcard route that matches ALL routes so none of the routes after it will get called unless that specific route calls next() to continue routing.
Top level wildcard routes are problematic for this reason. I would suggest avoiding them. There are temporary work-arounds like moving their definition to be the last top level route definition, but they can still be limiting for defining future routes because they are so greedy.
My recommendation would be to not make it a top level route:
router.get("/half/:half", onRequestHalf);
So, it won't conflict with the other top level routes and it essentially has it's own URL scope all to itself.

Express route: some routes are not recognised [duplicate]

I'm trying to wrap my head around my implementation of express.router() not triggering of the middleware function assigned to it.
I wrote a pretty big app and trying to add a few more endpoints to my path, but for some reason the 9th route gets loaded but does not trigger the function.
app.js
server.use(cors());
server.use(function (req, res, next) {
next();
});
server.use("/", express.static("./assets"));
server.use("/api", api);
server.use("/debug", debug);
server.use("/config", config);
server.use("/control", control);
server.use("/tools", files);
And this is where I declared my routes with the respective functions.
router.get("/teams", onGetTeams);
router.get("/players", onGetPlayers);
router.get("/achievements", getTop3);
router.get("/xpression", onXprPayload);
router.get("/snapshot", onRequestSnapshot);
router.get("/round-timeline", onRequestTimelinePayload);
router.get("/:half", onRequestHalf);
router.get("/dashboard-message", onSetDashboardMessage);
router.get("/get-match-odds", getTeamOdds);
function getTeamOdds(req, res) {
console.log("Sent odds");
res.json(odds);
res.end();
}
When I make the request for the last route, the function does not get executed, and I get back a 200 response.
Is there something big I'm missing?
Thank you !
Your route definition here:
router.get("/:half", onRequestHalf);
is a wildcard route that matches ALL routes so none of the routes after it will get called unless that specific route calls next() to continue routing.
Top level wildcard routes are problematic for this reason. I would suggest avoiding them. There are temporary work-arounds like moving their definition to be the last top level route definition, but they can still be limiting for defining future routes because they are so greedy.
My recommendation would be to not make it a top level route:
router.get("/half/:half", onRequestHalf);
So, it won't conflict with the other top level routes and it essentially has it's own URL scope all to itself.

Why express.js does not route binary file?

I have a file I want to access at the following URL:
http://127.0.0.1:400/db/signal/test.xlsx
And I have the following GET handler in my Express app:
app.get('/db/signal/', function (req, res) {
// handle route
});
When I browse to http://127.0.0.1:400/db/signal/, the handler is executed. But when I browse to http://127.0.0.1:400/db/signal/test.xlsx the handler fails to execute. Why?
I'm using Express version 4.
Thanks for your reply.
Express uses path-to-regexp to match paths. If you take a look at the API, you'll see that the string '/db/signal/' will only match exactly that path; it won't match any subpaths. To match that path and any subpath, just append an asterisk, like so:
app.get('/db/signal/*', (req, res) => { ... });
You can see more examples of matching patterns in the Express routing guide.

ExpressJS sendFile() cannot send URL GET parameters

I'm new to Node.js and Express.js and its routing. It's all set up correctly and it all works except for the following code.
I tried the following code:
app.get("/game/*", function(req, res) {
res.sendFile(__dirname + "/public/game.html?gameId=" + /\/([^\/]+$)/.exec(req.url)[1]);
});
The goal was to send all requests with /game/{gameId} (where gameId is some number) to /public/game.html?gameId={gameId}.
It correctly gets the requests with /game/, gets the gameId parameter from the URL, and attempts to sendFile() it. However, the sendFile() does not work, saying:
web.1 | Error: ENOENT, stat '/opt/lampp/htdocs/papei/public/game/32'
I've searched this error, and I guess it has to do with a file not being found. The problem is, /public/game.html exists. If I remove the ?gameId... part in the sendFile(), then it works. But I guess the sendFile() is looking for an exact URL, and is not finding it.
Is there any way to send URL GET parameters using ExpressJS?
I think the problem is that sendFile tries to find an exact match (which your query parameters break) as you thought.
You could use express-static to serve the html page, and then redirect to it as needed like so:
app.get("/game/:gameid", function(req, res) {
// Not ideal, as it uses two requests
res.redirect('/game.html?gameId=' + req.params.gameid)
});
Or you could put the html inside a template and render it for the response e.g:
app.get("/game/:gameid", function(req, res) {
// Render the 'game' template and pass in the gameid to the template
res.render('game', {gameid: req.params.gameid})
});
Either way, you don't need to use a catch all route and regex to get query parameters, see req.params or req.query in the express documentation.
Hope this helps.

Express 4 route handling with named parameters and router.param()

Is there a clean way to handle key/value query params in Express 4 routes?
router.route('/some/route?category=:myCategory')
I want to detect the presence of 'myCategory' in this route and use router.param([name], callback) to handle the associated logic.
router.param('myCategory', function(req, res, next, id) {
/* some logic here... */
});
The above 'router.param()' works fine if I have a route like /some/route/:myCategory but fails if I use
router.route('/some/route?category=:myCategory')
Am I doing something wrong here, or is this not supported in the Express 4 router out of the box?
Express treats properties after a ? as query params. So for:
/some/route?mycategory=mine
you would have to use:
req.query.mycategory or req.query['mycategory']
See this for more examples.

Resources