express.js - basic application router not working - node.js

I just creating a basic app, but it seems not working for me. any one help me to find the mistake?
here is my code :
import express from "express";
const app = express();
const router = express.Router();
app.use((req, res, next) => {
console.log("first middleware");
next();
});
router.get("/a", (req, res, next) => {
res.send("Hello this is route a");
});
router.post("/c", (req, res, next) => {
res.send("Hello this is route c");
});
app.listen({ port: 8000 }, () => {
console.log("Express Node server has loaded");
});
Node version : v14.17.5
Express version : ^4.17.1
thanks in advance.

Use the router
import express from "express";
const app = express();
const router = express.Router();
router.get("/a", (req, res, next) => {
res.send("Hello this is route a");
});
router.post("/c", (req, res, next) => {
res.send("Hello this is route c");
});
app.use(router, (req, res, next) => {
console.log("first middleware");
next();
});
app.listen({ port: 8000 }, () => {
console.log("Express Node server has loaded");
});

You need the app to consume the router.
Try adding app.use('/route', router);

Use app.use
Example
app.use('/c', c);

Related

Error handling problem with Nodejs and Express

I'm trying to handle errors produced in a Nodejs with Express app. I'm following Express error-handling guide but the errors didn't catched, and nothing appears on console and browser simply show Cannot GET /abc when request the incorrect url http://localhost:3000/abc
const express = require("express")
const app = express()
const port = 3000
const config = require("./config.js");
function logErrors (err, req, res, next) {
console.error(err.stack)
next(err)
}
function errorHandler (err, req, res, next) {
res.status(500)
res.render("error", { error: err })
}
app.all("/", function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
next();
});
app.get("/favicon.ico", (req, res) => res.status(204));
app.use(express.static("public"))
app.use("/zips/:idReq", express.static("zips"))
const generateZip = require("./generateZip")
const fmeForm = require("./fmeForm")
app.get("/", function (req, res) {
res.send("Hello World !")
})
app.use("/generateZip", generateZip)
app.use("/downloadForm", fmeForm)
app.use(logErrors)
app.use(errorHandler)
app.listen(port, () => console.log(`${config.nameServer} App listening on port ${port}`))
Any idea?
You need to include a common route handler to invoke error handling method at last
app.all('*', function (req, res, next) {
// Either invoke error handler method by raising new error
next(new Error('page not found'));
// Or simply return the response
res.status(404).send('page not found')
})

Node.js - Why checkAuthenticated middleware function cannot be exported from another file?

I have a node.js app that uses express, handlebars and passport.js for authentication. I have setup a routes folder for login
app.js
app.use('/login', require('./routes/login'));
routes/ login.js
const checkAuthenticated = (req, res, next) => {
if (req.isAuthenticated()) {
return res.redirect("/");
}
next();
};
router.get("/", checkAuthenticated, (req, res) => {
res.render("login");
});
module.exports = router;
This works fine.
However, if I put the checkAuthenticated middleware function in app.js then export and require it in login.js I get this error.
router.get() requires callback
app.js
app.use('/login', require('./routes/login.js'));
const checkAuthenticated = (req, res, next) => {
if (req.isAuthenticated()) {
return res.redirect("/");
}
next();
};
module.exports = { checkAuthenticated };
routes/login.js
const { checkAuthenticated } = require('../app.js');
router.get("/", checkAuthenticated, (req, res) => {
res.render("login");
});
module.exports = router;
Why doesn't it work when this function is required from another file like a normal function? I am trying to avoid duplication as I need exact same function for routes/register.js

Express Middleware flow

Consider the following Express app:
const express = require('express')
const app = express()
app.use((req, res, next) => {
console.log('\n\nALWAYS')
next()
})
app.get('/a', (req, res) => {
console.log('/a: route terminated')
res.send('/a')
})
app.use((req, res) => {
console.log('route not handled')
res.send('404 - not found')
})
app.listen(3000, () => {
console.log('listening on 3000')
})
Visit /a console result:
ALWAYS
/a: route terminated
ALWAYS
route not handled
Can somebody explain why is that there is another middleware log? I was expecting only 2 lines of console log. Instead
ALWAYS
route not handled
has been logged.
This is a very common point of confusion. The likely cause is that you went to /a in the browser and the browser made two requests. One for /favicon.ico and one for /a (that's what browsers do when you go to a new site they haven't previously cached the favicon for - the little glyph they display that represents the web site in some places in the browser).
If you log the request URL in your middleware and in your 404 handler, you will see the details of what is happening:
const express = require('express')
const app = express()
app.use((req, res, next) => {
console.log('\n\nRequest for: ', req.url);
next();
})
app.get('/a', (req, res) => {
console.log('/a: route terminated')
res.send('/a')
})
app.use((req, res) => {
console.log('route not handled for ', req.url);
res.send('404 - not found');
});
app.listen(3000, () => {
console.log('listening on 3000')
})

Switch between routers Express

I want to display a website completely different in function of an arbitrary value.
Let's say I have two routers
const express = require('express');
const app = express();
const router1 = express.Router();
router1.get('/', (req, res, next) => res.json({message: 'I am the router1'}))
const router2 = express.Router();
router2.get('/', (req, res, next) => res.json({message: 'I am the router2'}))
app.use((req, res, next) => {
if(Math.random() > 0.5) {
// Use router1
} else {
// Use router2
}
})
I have no idea how I can do that. I will have a lots of routes (router.get, router.post) I don't want to check that on each route
Thanks
Just return a call to the router:
app.use((req, res, next) => {
if(Math.random() > 0.5) {
return router1(req, res, next)
} else {
return router2(req, res, next)
}
})
This can also be done by usage of .next('router') method.
Here is an example:
const router1 = express.Router();
router1.use((req, res, next) => {
console.log("This gets called everytime!");
if(Math.random() > 0.5)
next('router');//skip to next router object
else
next();//continue with current router
});
router1.get('/',(req, res, next) => {
console.log("Continuing with current router");
res.send("Continuing with current router");
});
const router2 = express.Router();
router2.get('/', (req, res, next) => {
console.log("Skipped Router 1, continuing with router 2");
res.send("Skipped Router 1, continuing with router 2");
});
//binding both routers here
app.use("*", router1, router2);
.next('router') basically skips to next router object, which has been mentioned in the app.use line, if only next() is used then it continues with current router methods.
Why not just?
if(Math.random() > 0.5) {
app.use(router1);
} else {
app.use(router2);
}

A lot of "express routers" in a single Bookshelf transaction

Bookshelf transaction is working only in callback function. How i can do it?
var express = require('express');
var router = express.Router();
router.post('/', (req, res, next) => {
Bookshelf.transaction((trx) => {
req.trx = trx;
next();
});
});
router.post('/', (req, res, next) => {
// use req.trx
});
router.post('/', (req, res, next) => {
// use req.trx
});
router.post('/', (req, res, next) => {
req.trx.commit();
});

Resources