the router doesn't select correct function - javascript

When I use postman to login a user with http://localhost:3000/login but it always run the register function. Code runs ok, it just routes to wrong function. How to redirect it to login when the url is login and vice-versa. Both the login and register functions are in the same authentication.js file.
controllers/authentication.js
exports.register = (req, res) => {
[Some long code here]
});
exports.login = (req, res, next) => {
[Some long code here]
});
routes/index.js
const express = require("express");
const ctrlAuth = require("../../controllers/authentication");
const router = express.Router();
router.post('/', ctrlAuth.register);
router.post('/', ctrlAuth.login);
module.exports = router;
app.js
const userRoutes = require("./app_api/routes/index");
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use("/login", userRoutes);
app.use("/register", userRoutes);
module.exports = app;

The reason here is everytime a route starting with login or register hits your express server it is routed to userRoutes file as both login and register path segment use same routing file as per your code.
app.use("/login", userRoutes); // ---> pointing to userRoutes
app.use("/register", userRoutes); // ---> pointing to userRoutes
Once express moves to userRoutes the path segment left to match is "/" and method type POST. And the first route satisfies both the condition. Hence API call always end up being served by the register handler.
// match found here for "/" segment and post method type
router.post('/', ctrlAuth.register);
// --> this route is never reached
router.post('/', ctrlAuth.login);
ANSWER
To overcome this problem you can make these changes in your files.
app.js
Remove these lines:
app.use("/login", userRoutes);
app.use("/register", userRoutes);
Replace With:
app.use("", userRoutes);
routes/index.js
Remove these lines:
router.post('/', ctrlAuth.register);
router.post('/', ctrlAuth.login);
Replace With:
router.post('/register', ctrlAuth.register);
router.post('/login', ctrlAuth.login);

Related

Express Routes not functioning

I am trying to create a route to my users file as well as others but when I use postman to send a get request to https://localhost:3000/api/users I get a "Cannot GET api/users/ error.
I have tried putting the require statement into a variable and then passing it to the app.use() function. I also made sure the in my users.js file that the first parameter is only a "/". Also it is not just the users route it is all of my routes that do not work. Can someone see my mistake?
Here is the server.js file
const express = require("express");
const connectDB = require("./config/db");
const app = express();
//Connect DB
connectDB();
app.get("/", (req, res) => res.send("API Running"));
//define routes
const userRoute = require("./routes/api/users");
app.use("api/users", userRoute);
app.use("api/auth", require("./routes/api/auth"));
app.use("api/profile",
require("./routes/api/profile"));
app.use("api/posts", require("./routes/api/posts"));
const PORT = process.env.PORT || 3000;
app.listen(PORT, () =>
console.log(`Server started on port: ${PORT}
`)
);
And here is the users.js file, all of the other router files are similar just with different names.
const express = require("express");
const router = express.Router();
// #route get api/users
// #desc test route
// # access Public
router.get("/", (req, res) => res.send("User Route"));
module.exports = router;
I also tried changing the last line in users.js to export default router but that just resulted in an unexpected token error. Thank you in advance for the help.
Add '/' before your route definitions in the server.js file. So your route definition for the users will be app.use("/api/users", userRoute). Do the same for all your route definitions
Just replace your line app.use("api/users", userRoute); to app.use("/api/users", userRoute); in server.js

How to import routes in polka js similar to express.Route()

I am trying to import route logic from another file. In express js this is achievable via express.Route(), when i tried polka.Route() an error pops up saying Route doesn't exist in polka.
Express Implementation
server.js
const express = require('express');
const users = require('./routes/api/users');
const app = express();
app.use('/users', users);
user.js
const express = require('express');
const router = express.Router();
router.get('/test', (req, res) => res.json({ msg: 'works' }));
module.exports = router;
When /users/test is hit the output is {msg:'works'}. This works for the express implementation. For the polka implementation i changed the word express to polka installing it. The issue arises on the line polka.Router() of user.js. How do i enable this functionality of importing route logic from another file in polka.
The polka micro web server does not implement a difference between routers and the app. In your users.js file simply setup your routes as you would in your server.js file and then module.export. See Below:
Polka Implementation
server.js
const polka = require('polka');
const users = require('./routes/api/users');
const app = polka();
app.use('/users', users);
user.js
const polka = require('polka');
const router = polka();
router.get('/test', (req, res) => res.end(JSON.stringify({ msg: 'works' })));
module.exports = router;
Hope this help!
Also, here is a good link to see other differences between Express.js and Polka.js: https://github.com/lukeed/polka#comparisons

Correct format for Node architecture (BASIC)

Introduction
I have built some back end functionality in Node (First time using Node). Problem is that the whole thing was built in one page (index.js) so now im following a few basic tutorials and setting out express router middleware and now trying to follow a modular MVC approach,
This code is simple but brakes when I separate into two pages Server.js and config.js. I know its a simple problem but i cant spot it. can someone help spot the problem and maybe improve the structure ?
Problem
I go to http://localhost:8080/about or a different route and I get
Cannot GET /about
rather than the correct print out.
back-end/server.js
var express = require('express');
var app = express();
var port = process.env.PORT || 8080;
// get an instance of router
var router = express.Router();
// START THE SERVER
// ==============================================
app.listen(port);
console.log('Server has started!! ' + port);
back-end/config.js
router.use(function(req, res, next) {
console.log(req.method, req.url);
next();
});
router.get('/', function(req, res) {
res.send('im the home page!');
});
// sample route with a route the way we're used to seeing it
router.get('/sample', function(req, res) {
res.send('this is a sample!');
});
router.get('/about', function(req, res) {
res.send('im the about page!');
});
app.route('/login')
.get(function(req, res) {
res.send('this is the login form');
})
.post(function(req, res) {
console.log('processing'); // shows on console when post is made
res.send('processing the login form!'); // output on postman
});
app.use('/', router);
As #SLaks said in his comment, you need to import (require) your backend/config.js file. But it's not as simple as that...
In node, variables are scoped to the file in which they appear, so if you simply add require('./config') to your server.js file, that's not going to work either, because the router variable in config.js is local to that file - it's not going to know about the router variable in server.js.
The solution to this is to have the config.js file export a function which the server.js file can use to configure stuff. For example
config.js
module.exports = function(router) {
// set up your router here with router.use, etc.
};
server.js
var configure = require('./config');
// after you set up your express router...
configure(router);
// now start listening

react router and express GET conflict

I'm not able to figure out how react router and express route working together.
I have this
app.get('*', function(req, res) {
res.sendFile(path.resolve(__dirname) + '/server/static/index.html');
});
// routes
const apiRoutes = require('./server/routes/api');
app.use('/api', apiRoutes);
The problem is my api can't use GET because it will redirect to index.html. If I remove the wildcard route, then react-router would not be able to work properly.
Your app.get('*') statement will match any request coming in. You can fix your problem by changing the order of the statements:
// routes
const apiRoutes = require('./server/routes/api');
app.use('/api', apiRoutes);
app.get('*', function(req, res) {
res.sendFile(path.resolve(__dirname) + '/server/static/index.html');
});
This way, any requests whose path's start with /api will be handled by your apiRoutes router, all the others are handled by the asterisk.

Express error - TypeError: Router.use() requires middleware function but got a Object

I am getting this error when I run npm start to run my express app.
TypeError: Router.use() requires middleware function but got a Object
my app.js code
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 routes = require('./routes/index');
var users = require('./routes/users');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
// 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({ extended: true }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', routes);
app.use('/users', users);
/// catch 404 and forwarding to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
/// error handlers
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
});
});
}
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});
module.exports = app;
my index.js code
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res) {
res.render('index', { title: 'Express' });
});
/* GET Hello World page. */
router.get('/helloworld', function(req, res) {
res.render('helloworld', { title: 'Hello, World!' })
});
module.exports = router;
I am quirte new to using Node and express. I cant see where I have gone wrong. Can anybody see what my problem is?
I found the answer in the comments from Kop4lyf:
check your users.js. It should also be exporting the router like
index.js, if you can try that.
However, this question was my top search result when I ran into this issue, so I am promoting to an answer.
The error is caused because one of your route modules is not being exported - meaning Express does not have access to it when it tries to identify all of your routes.
You can fix this by adding module.exports = router; to the end of each of your route files.
Example:
var express = require('express');
var router = express.Router();
router.get('/', function(req, res, next) {
//Do whatever...
});
module.exports = router;
More information about module.exports can be found on this question or the offcial Node.js documentation.
I have fixed this by adding which i am using somewhere. So please check your all exports.
module.exports = router;
If you use in routes
exports default router
Your solution can be
module.exports = router
I had the same error , fixed it by replacing app.use('view engine', 'ejs') with app.set('view engine', 'ejs').
For reference I used this webpage Migrating from 3.x to 4.x
I didn't have to make any changes to either index.js or application.js. For more information on EJS one could refer Using EJS with Express and Express 4.x API
Your index.js file is fine you just have to create users.js and export it.
let express = require('express');
let router = express.Router();
//Login Page - GET REQUEST
router.get('/login',(req,res)=> {
res.send('login page');
})
//Register Page - GET REQUEST
router.get('/register',(req,res)=> {
res.send('register page');
});
module.exports = router;
in every module **export the router** and **keep one handler for the default
path '/'**
// in index.js
const authRoute = require("./routes/authRoute");
app.use("/auth", authRoute);
// in authRoute.js
const express = require("express");
const router = express.Router();
router.get("/", (req, res) => {
// code
});
module.exports = router;
This error comes when you forgot to export the module which uses the Router.
Your mentioned code works perfectly with some tweaks.
if your app.js is main/starting point of the app.
it should have
const port = process.env.PORT || 3000;
app.listen(port, () => console.log(`Listening on port ${port}...`));
instead of
module.exports = app;
(optional)Generally index.js is used for starting point of app. Rename index.js as helloworld.js and change same at require statement
var routes = require('./routes/index');
to
var routes = require('./routes/helloworld');
run this app using the following command
node app.js
If you have checked all the solution than also having this error than check this one
Another cause of having this error is calling a method which is not exist or not not exported.
In my case i am calling login method but i forgot to define them
I was trying to call this method
app.post('/api/login', db.login);
but i had forgot to create login method so i got this error. also try to check spelling mistake may be you might have typed wrong spell
I had the same problem, and then I discovered that I was missing this line in one of my controllers !
return api; //it might be return routerfor your code !
I added this line to my code and it worked fine.
Whew, my problem was that i was doing module.exports = { router } instead of module.exports = router
I found it after lot of struggle! as everything syntactically correct, nothing wrong with code that was written, it was due to the code that was not written yet! This could happen if you have implemented index.js but not yet users.js. However, you have already defined both lines
app.use('/', routes);
app.use('/users', users);
If you are eager to test index.js right away without waiting for users.js to be implemented. That's exactly when it errors out.
if you are still facing this problem and try every solution then just replace router with routes and it worked fine
For anybody using EJS:
In my case I was receiving this error as I used
app.use("view engine","ejs")
instead of
app.get("view engine","ejs")
I fixed it by removing the app.use(/users, users);
I don't need this at the minute so maybe that is why it started breaking.

Categories

Resources