Using multiple router defined in their own files in express - javascript

I am new to Node.js and express framework. I am getting an error when I am trying to go to the signuplogin route from my homepage route. I have also tried all the similar questions in the stackoveflow, but none of them have worked for me, so I thought of posting my own.
This is my app.js
var homepage = require('./routes/homepage');
var signupLogin = require('./routes/signuplogin');
var app = express();
app.use("/", homepage);
app.use("/signup-login", signupLogin);
This is my homepage.js in routes directory
var express = require('express');
var homepageRouter = express.Router();
/* GET Homepage. */
homepageRouter.get("/", function(req, res, next) {
res.render('../views/homepage/homepage.hbs');
});
module.exports = homepageRouter;
This is my signup-login.js in routes directory
var express = require('express');
var signupLoginRouter = express.Router();
/* GET Signup Login Page. */
signupLoginRouter.get("/signup-login", function(req, res, next) {
res.send('respond with a resource');
});
module.exports = signupLoginRouter;
Well my "/" route works perfectly but it says 404 when I try to access "/signup-login" route.
I also changed the route to "/signuplogin" because I thought maybe it doesn't except the "-" character in the route. But that didn't work as well. Any solution/advice?

You have done a mistake in your signup-login.js file. Correct the code with this -
/* GET Signup Login Page. */
signupLoginRouter.get("/", function(req, res, next) {
res.send('respond with a resource');
});
As per your code the actual url of signup page becomes to "/signup-login/signup-login"
You don't need to add the singup-login url path again in your page. That is already referenced in your main router.

Related

Basic Express Routes puzzle

I got stuck in Mozilla js tutorial and need help. Here are excerpts from 3 files:
a)
the 2 pieces from app.js file show where to find Router handlers and then where to present them (my guess)
//app.js
//the following 3 vars do sit in routes folder, code copy-pasted var 3 my addition
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var coolRouter = require('./routes/cool');
var app = express();
....
//the following 2 'use' work just fine, the third sends err 404, 'not found'
app.use('/', indexRouter);
app.use('/users', usersRouter);
app.use('/users/cool', coolRouter);
b) part of the users.js sitting in routes folder:
/* GET users listing. */
router.get('/', function(req, res, next) {
res.send('respond with a resource');
});
c) part of the cool.js copied from the previous and sitting in routes folder:
/* GET cool text. */
router.get('/', function(req, res, next) {
res.send('you are cool, kid!');
});
I'd like to get it why it does not work.
The reason you cannot reach /users/cool is that your request is being cathed by the /users endpoint.
In order for your code to work as you intend it to do, you will have to place your routes like this:
app.use('/', indexRouter);
app.use('/users/cool', coolRouter);
app.use('/users', usersRouter);
With the /users/cool endpoint before the /users endpoint. That way, the request to /users/cool will not be catched by another endpoint.

A routing problem with workbox vuejs in production and express

I am creating a forum application to learn about VueRouter in Express. What I am trying to do is create a routing in vuejs and then take it to production. When I compile everything works fine. The view files go directly to the public folder in express and work almost perfect. I can change the route perfectly but when I touch CTRL + F5 from a different route to the main one, it returns a GET error.
For example this is my index and work perfect:
I can even change the route:
I touch F5 and reload the page without any problem, but when I touch CTRL + F5 to make the request again, obviously it returns an error because I don't have the route declared in express,
but vuejs returns only one html index as a view, I can't render any other files because they don't exist.
These public folder at image are the files created by vue by the build command:
This is my express configuration:
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var indexRouter = require('./routes/index');
var usersNotifications = require('./routes/notifications');
var usersNotifications = require('./routes/notifications');
var app = express();
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);
app.use('/notifications', usersNotifications);
module.exports = app;
this is my index route on express:
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index');
});
module.exports = router;
The only option I have is to render the only index that vuejs offers. How can i Fix that?
The other problem is that I would not like these console workbox messages, how can i remove them so they never appear:
and this is the vuejs registerServiceWorkers.js file:
/* eslint-disable no-console */
import { register } from 'register-service-worker'
if (process.env.NODE_ENV === 'production') {
register(`${process.env.BASE_URL}service-worker.js`, {
/***
* Note that here were some methods also display messages
* on the console and I deleted them. Methods like
*/
})
}
Any ideas?
Since vue router is handling page routing, you'll have to render index for all requested paths like:
router.get('*', function(req, res, next) {
res.render('index');
});
// in server
app.use('*', indexRouter);
If you're exposing other endpoints from server you'll have to mount this as the last route middleware like, say in your case:
app.use('/notifications', usersNotifications);
app.use('*', indexRouter);

Express-subdomain routing not working correctly?

I have been looking for solutions for a couple days now trying to google it and all and now i am here. I am trying to setup subdomains for my app using express-subdomain package. However in the example below the app ALWAYS returns app.get route and skips the other subdomain routes specified.
I have also in turn added the hosts file url so i know that should not be the issue.
It must be in my code for some reason it always ends up displaying Detect Region route even when accessing oce.localhost:3000.
Please help me :)
Server.js
var subdomain = require('express-subdomain');
var express = require('express');
var app = express();
// Region routes
var router = express.Router();
var na = require('./routes/region/na.js');
var oce = require('./routes/region/oce.js');
router.use(subdomain('na.localhost', na));
router.use(subdomain('oce.localhost', oce));
app.get('/', function(req, res) {
res.send('Detect Region and send to correct subdomain!');
});
app.listen(3000);
routes/region/oce.js
var
express = require('express'),
router = express.Router();
router.get('/', function(req, res) {
res.send('Your are in OCE Region!');
});
module.exports = router;
And na.js is pretty much the name as oce.js
Cheers
You are setting your subdomains in the router variable but you don't tell your app to use it.
You have to do that :
app.use(router);
You put it in place of your current app.get.
Edit
You could also put your app.get after the app.use(router) so that it will act as a default route. (When you are neither on oce or na, it will use it)
Edit after some testing
Alright I've been able to make it work using express-vhost. I just updated your server.js like so :
var subdomain = require('express-vhost');
var express = require('express');
var app = express();
// Region routes
var router = express.Router();
var na = require('./routes/region/na.js');
var oce = require('./routes/region/oce.js');
subdomain.register('na.localhost', na)
subdomain.register('oce.localhost', oce)
app.use(subdomain.vhost(app.enabled('trust proxy')));
app.get('/', function(req, res) {
res.send('Detect Region and send to correct subdomain!');
});
app.listen(3000);

Why am I getting "name undefined" when trying to post using Express and Body Parser

I'm attempting to build a MEAN app and trying to test POSTing with POSTMAN. When I do, I keep getting the dreaded "TypeError: Cannot read property 'name' of undefined". If I type in a simple string, the POST goes through fine. But when I use "req.body.name" I get the error. I've looked in every place and I'm not seeing my mistake. I even followed the suggestions on this thread with no luck. Any help or suggestions would be greatly appreciated.
Here's the code I am currently working with in my server.js file:
const express = require('express');
var bodyParser = require('body-parser');
var Bear = require('./models/bear')
var path = require('path');
var mongoose = require('mongoose');
var router = express.Router();
var app = express();
var staticAssets = __dirname + '/public';
app.use(express.static(staticAssets));
app.use('/api', router)
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
// Routes for my API
//===================================
// middleware to use for all requests
router.use(function(req,res,next){
// logging happens here
console.log('Something will happen.');
next(); // Head to the next router...don't stop here
});
// Test router to make sure everything is working (accessed at GET http://localhost:3000/api)
router.get('/', function(req, res){
res.json({message: 'hooray! welcome to our api!'})
})
//More routes will happen here with routes that end in "/bears"
router.route('/bears')
//Create a bear (accessed at POST http://localhost:3000/api/bears)
.post(function(req,res){
var bear = new Bear(); // Create a new instance of the bear model
console.log(req);
bear.name = req.body.name; // set the bears name (comes from the request)
//res.send(200, req.body);
bear.save(function(err){
if (err)
res.send(err);
res.json({message: 'Bear Created!!'});
});
});
//======================================
//var Products = require('./products.model.js');
var Product = require('./models/product.model');
var db = 'mongodb://localhost/27017';
mongoose.connect(db);
var server = app.listen(3000);
console.log("App is listening on port 3000");
Thanks.
Also, the url I'm trying to use inside of POSTMAN is http://localhost:3000/api/bears
Express processes requests Top-Down, meaning if you require a piece of functionality to be applied to all routes via middleware, than that middleware needs to be added to your app before any routes that require it. This is usually the case for middleware such as body-parser.
When using Router Middleware, you don't typically construct the router in the same file as the actual Express app that will use it as middleware. Instead, place it in a separate file and/or directory for organization purposes, this is considered a best practice.
Express Apps can be structured like so
/lib
/models
bear.js
product.js
/node_modules
/public
/css
/routes
api.js
package.json
server.js
The routes directory is where you would place any applicable Router Middleware files such as your api router. server.js is your main Express App and public is where your static assets are stored. lib is directory that contains any business logic files and models.
The actual Express app and Router files should look something like this
server.js
'use strict';
const express = require('express');
const bodyParser = require('body-parser');
const path = require('path');
const apiRouter = require('./routes/api');
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.static(path.join(__dirname, public)));
app.use(/api, apiRouter);
app.listen(port, () => {
console.log(`Listening on port ${port});
});
module.exports = app;
routes/api.js
'use strict';
const router = require('express').Router();
const Bear = require('./lib/models/bear');
router.use((req, res, next) => {
// logging happens here
console.log('Something will happen.');
next(); // Head to the next router...don't stop here
});
router.get('/', (req, res) => {
return res.json({ message: 'hooray! welcome to our api!'})
});
router.route('/bears')
//Create a bear (accessed at POST http://localhost:3000/api/bears)
.post((req, res) => {
var bear = new Bear(); // Create a new instance of the bear model
console.log(req);
bear.name = req.body.name; // set the bears name (comes from the request)
//res.send(200, req.body);
bear.save((err) => {
if (err)
return res.send(err);
return res.json({message: 'Bear Created!!'});
});
});
module.exports = router;
To note, you could break up your API even further to increase the amount of decoupling. An example of this would be to move the /api/bear route to its own router middleware and into its own route file. Then simply add it to your routes/api.js router as a middleware like you would in server.js. If your app is going to have a decent sized API, then this would be the best approach because it would allow the most flexibility when it comes to applying middleware to only certain routes and would make maintaining the source much easier.

Node, Express - CANNOT GET route

I am building an Express app and having some issues with routing. My '/' route is working perfectly, however other routes are not. I've looked into other questions people have posted and these have not resolved my issues.
I have a routes/index.js file:
module.exports = function(app){
app.use('/', require('./routes/home'));
app.use('/about', require('./routes/about'));
}
My routes/home.js: - WORKING!
const express = require('express');
const router = express.Router();
router.get('/', function(req, res) {
res.render('app/home');
});
module.exports = router;
My routes/about.js: - NOT WORKING!
const express = require('express');
const router = express.Router();
router.get('/about', function(req, res) {
res.render('app/about');
});
module.exports = router;
When I go to '/about' I see this error in the browser - 'Cannot GET /about'
Both the home.html and about.html files are located in the same views directory.
Any help here would be very appreciated!
let me quote from express doc:
A route will match any path that follows its path immediately with a “/”. For example: app.use('/apple', ...) will match “/apple”, “/apple/images”, “/apple/images/news”, and so on.
see express doc
this is "not working" because you set the /about in the app.use and in the router.get. try to request /about/about and you will see that this is working (just not as you wanted to)..
now just change the /about in the routes/about.js then rerun and try to request /about and it will work :)
Your route is set to /about/about.
Change about.js to this:
const express = require('express');
const router = express.Router();
router.get('/', function(req, res) {
res.render('app/about');
});
module.exports = router;

Categories