Express.js main router working, but others routers on him not - javascript

I have the problem on routers. My main route /weather working, but others routers on him don't.
app.js
const express = require('express');
const weatherRoute = require('./back/routes/weatherRouter.js');
const app = express();
app.use(bodyParser.json());
app.disable('etag');
app.use('/weather', weatherRoute);
weatherRouter.js
const router = express.Router();
router.get('/', async (req, res) => {
try {
const wholeData = await WeatherInfo.find();
res.json(wholeData);
} catch (err) {
res.json({ message: err })
}
});
router.get('/now', (req, res) => {
res.send("ITS NOT WORKING");
});
module.exports = router;
the problem is that localhost:5000/weather working perfect, but when I want to use some other routers on that Route e.g. localhost:5000/weather/now that's not working
Any ideas what I'm doing wrong ?
UPDATED :
it works, when between those routers is no others routers.
e.g.
router.get('/', async (req, res) => {
//working
}
router.post('/:add', async (req, res) => {
//working
}
router.get('/now', async (req, res) => {
//doesnt work
}
If I move /now above /add router it works perfect. Can someone explain why is this happening ?

Define actual path in path section likerouter.post('/weather/now', (re, res) => {
//Handel re
}

I found the solution.
The routers position is matter. Reference to explanation
My last router didn't work, because another router already catched him.
app.get('/:add', function (req, res) {
// this will match all /a, /b .. including /new
res.end('done!');
});
app.get('/now', function (req, res) {
// this is never called
res.end('done!!');
});

Related

Attempting to set up static HTML pages using express

I am trying to set up a few pages so that when a user goes to locahost:number/war . They can see the /war page. But when I run the server I get a "Cannot GET war" error on the page. I've set it up similar to this before and didnt have an issue.
I also get a "ReferenceError: __dirname is not defined" issue on the console
import express from 'express';
const app = express();
const router = express.Router();
import path from 'path';
import {getData} from './server.js'
// HTML Routes
router.get('/', (req,res)=> {
res.sendFile(path.join(__dirname, "../start.html"));
})
router.get('/war', (req,res)=> {
res.sendFile(path.join(__dirname, "../index.html"));
})
router.get('/score', (req,res)=> {
res.sendFile(path.join(__dirname, "../finalScore.html"));
})
// Data
export async function sendStats(){
app.get("/data", (req,res)=> {
const data = getData()
res.json(data)
})
app.post("/data",(req, res) => {
const {name, score} = req.body
const data = createData(name, score)
res.json(data)
} )
app.use((err, req, res, next) => {
console.log(err.stack)
res.status(500).send('Something Broke!')
})
app.listen(7171, ()=> {
console.log('Server is running on port 9191')
})
}
const data = await sendStats();
You forgot to load the router in the app:
app.use('/', router)

Cannot GET error for Express routing with parameters :

I'm getting a Cannot GET error when I try express routing with parameters for the first time and I don't know why.
It worked fine and I installed lodash and now nothing works anymore.
Here`s the code:
app.get("/posts/:postName"), function (req, res) {
let requestedTitle = req.params.postName;
posts.forEach(function(post) {
let storedTitle = post.title;
if (storedTitle === requestedTitle) {
console.log('match found');
} else {
console.log('no match found');
}
});
};
I'm using Localhost and when I try to run it it gives me a Cannot Get error.
For example I enter: http://localhost:3000/posts/test
And usually it kept me on the home route and console logged if it matched one of my entries before or not.
I have Express installed and everything heres the complete code. But it just won't work anymore after installing lodash, do you guys see an error somewhere here? I'm staring at this for 3 days now lol:
//jshint esversion:6
const express = require("express");
const bodyParser = require("body-parser");
const ejs = require("ejs");
const _ = require('lodash');
const homeStartingContent = "text";
const app = express();
let posts = [];
app.set('view engine', 'ejs');
app.use(bodyParser.urlencoded({extended: true}));
app.use(express.static("public"));
app.get("/", function(req, res) {
res.render(__dirname + "/views/home.ejs", {homeStartingContent: homeStartingContent, posts: posts});
});
app.get('/about', (req, res) => {
res.render('about', {aboutContent: aboutContent});
});
app.get('/contact', (req, res) => {
res.render('contact', {contactContent: contactContent});
});
app.get('/compose', (req, res) => {
res.render('compose');
});
app.post('/compose', (req, res) => {
posts.push(req.body);
console.log(posts)
res.redirect('/')
});
app.get("/posts/:postName"), function (req, res) {
let requestedTitle = req.params.postName;
posts.forEach(function(post) {
let storedTitle = post.title;
if (storedTitle === requestedTitle) {
console.log('match found');
} else {
console.log('no match found');
}
});
};
app.listen(3000, function() {
console.log("Server started on port 3000");
});
In the Express documentation it showed this code example and I feel my code should definitely work. I don't understand why it is not.
app.get('/users/:userId/books/:bookId', (req, res) => {
res.send(req.params)
})
Notice the closing parentheses:
app.get("/posts/:postName"), function (req, res) {
^
It shouldn't be there, but at the end of the handler function.

Node: Cannot acces to an endpoint

I have no idea about what is happend. I've developed a server who serves information through an API REST. I have defined several endpoints which works without any problem but the end points defined today doesn't work anyone of them.
The code of my router.js is:
import express from "express";
import {Result} from "../com/result";
import config from "../config";
import {getData, getPhotoFromGIATAServer} from "../com/functions";
import {XMLParser} from "fast-xml-parser";
import fs from "fs";
const router = express.Router();
router.post("/api", async (req, res) => {
});
router.post("/api/destinations", async (req, res) => {
});
router.post("/api/country", async (req, res) => {
});
router.post("/api/media", async (req, res) => {
});
router.post("/api/factsheet", async (req, res) => {
});
router.post("/api/texts", async (req, res) => {
});
router.post("/api/update", async (req, res) => {
});
router.post("/api/photo", async (req, res) => {
});
router.post("/api/update/photos", async (req, res) => {
//Doesn't work
});
router.post("/api/update/texts", async (req, res) => {
//Doesn't work
});
router.post("/api/update/factsheets", async (req, res) => {
//Doesn't work
});
module.exports.Router = router;
All the endpoints works fine except the last three ones. When I make a call to one of them I receive a 404 error.
As you can see, the domain and por in both cases are equals but one of them works and the other one not.
I don't understand anything. What is happend? What am I doing wrong?

How can I split server.js in the right way?

I am writing my own app (both of back and frontend). I want to ask you guys if I am doing it in the right way.
I want to split server.js to a few files (in PHP I would use include() for it) but I am not sure if it is the right way.
Here is some code example:
const app = require('express')(),
fs = require('fs'),
http = require('http').Server(app),
io = require('socket.io')(https),
path = require('path'),
login_user = require('./routes/login_user'),
add_user = require('./routes/add_user'),
logout = require('./routes/logout');
app.post('/login_user', (req, res, next) => {
login_user.go(req, res, next);
});
app.post('/add_user', (req, res) => {
add_user.go(req, res);
});
app.get('/logout', (req, res) => {
logout.go(req, res);
});
Please note that's not the whole code and I want to focus on spliting "routes" or "paths" to a few files. For example a whole API login system is in /routes/login_user.js file (exported).
Now I have got so many paths and code is looking a little bit weird.
app.post('/check_balance', (req, res) => {
check_balance.go(req, res);
});
app.post('/add_incoming', (req, res) => {
add_incoming.go(req, res);
});
app.post('/add_outgoing', (req, res) => {
add_outgoing.go(req, res);
});
app.post('/add_category', (req, res) => {
add_category.go(req, res);
});
app.post('/change_settings', (req, res) => {
change_settings.go(req, res);
});
app.post('/login_user', (req, res, next) => {
login_user.go(req, res, next);
});
app.post('/add_user', (req, res) => {
add_user.go(req, res);
});
app.post('/verify_user', (req, res) => {
verify_user.go(req, res);
});
app.get('/logout', (req, res) => {
logout.go(req, res);
});
app.get('/check_settings', (req, res) => {
check_settings.go(req, res);
});
app.get('/check_categories', (req, res) => {
check_categories.go(req, res);
});
app.post('/remove_categories', (req, res) => {
remove_categories.go(req, res);
});
app.get('/check_incomings', (req, res) => {
check_incomings.go(req, res);
});
app.get('/check_outgoings', (req, res) => {
check_outgoings.go(req, res);
});
app.get('/check_both', (req, res) => {
check_both.go(req, res);
});
app.get('/check_outgoings_chart', (req, res) => {
check_outgoings_chart.go(req, res);
});
app.get('/check_incomings_chart', (req, res) => {
check_incomings_chart.go(req, res);
});
app.post('/remove_incomings', (req, res) => {
remove_incomings.go(req, res);
});
app.post('/remove_outgoings', (req, res) => {
remove_outgoings.go(req, res);
});
Make your server.js as simple as possible and extract all your routing logic to separate folder (possibly name it "routes"). If you also want to define yours schema, put it in separate folder ("models"). A complete solution can be like this:
in Model Folder:
user.js
const mongoose = require("mongoose"); // In case if you want to use MongoDB
const userSchema = new mongoose.Schema({
name: { type: String, required:true },
email: { type: String, required: true },
password: { type: String, required: true },
});
exports.User = User;
In routes folder:
users.js
const { User } = require("../models/user");
const router = express.Router();
//define your routes here
router.get('/', async(req,res)=>{
const users = await User.find();
res.send(users)
});
module.exports = router;
And finally in your server.js
const app = require('express')(),
fs = require('fs'),
http = require('http').Server(app),
io = require('socket.io')(https),
path = require('path'),
users = require('./routes/users');
app.use("/api/users", users); //With this API Endpoint you can access it like http://{your_domain}/api/users
If you want to make it more clean, you can wrap all routing paths to another folder. Lets call it "startup".
with this you can do like this.
in your startup folder:
routes.js
const users = require("../routes/users");
module.exports = function(app) {
app.use("/api/users", users);
//add all routes here
}
Then in your server.js
require("./startup/routes")(app); //all routes will be imported
I think this is what you need.
Let's say that there is a file called routers/login.js:
var express = require('express');
var router = express.Router();
router.get('/login', function(req, res) {
// do something
});
then app.js:
...
var login = require('./routes/login');
app.use("/login", login)
Put all the routes files in a folder with multiple files like User_routes.js can contain routes related to user and so on.
Also all you need to then is to export these routes from each file by using module.export.your_module and include them in your server file like in user routes :
// Login Page
router.get('/login', (req, res) => res.render('login'));
// Register Page
router.get('/register',(req, res) => {
res.render('register'); });
then import it as
module.exports = router;
also include it as :
app.use('/users', require('./routes/users.js'));
app.use('/',(req,res,next)=>{
console.log('I should handle it Now.');
res.render('404');
});

express.js - single routing handler for multiple routes

I'm currently building an app and I have a routes file that looks like this.
const router = require('express').Router();
router.get('/', (req, res) => res.render('statics/home'));
router.get('/jobs', (req, res) => res.render('statics/jobs'));
router.get('/about-page', (req, res) => res.render('statics/about-page'));
router.get('/valves', (req, res) => res.render('statics/valves'));
router.all('*', (req, res) => res.notFound());
module.exports = router;
I am trying to figure out a way to refactor my routes and have a single route that accepts any string and then checks to see if a file exists matching it
Any help appreciated!
To easily handle static file, you can use express static, express will automatic route all file inside static folder
app = require('express')();
app.use('statics',express.static('statics'));
Something like this could work:
const router = require('express').Router();
const fs = require('fs');
router.get(':template', (req, res) => {
const tpl = req.param('template');
if (tpl) {
if (fs.existsSync('/path/to/templates/' + tpl + '.ext')) { // adjust the path and template extension
res.render('statics/' + tpl);
} else {
res.notFound();
}
} else {
res.render('statics/home');
}
});
router.all('*', (req, res) => res.notFound());
module.exports = router;
Or probably better approach would be to read the templates directory once and create routes based on its contents:
const router = require('express').Router();
const fs = require('fs');
const templates = fs.readdirSync('/path/to/templates');
templates.forEach(tpl => {
tpl = tpl.substring(tpl.lastIndexOf('/') + 1);
if (tpl === 'home') {
router.get('/', (req, res) => res.render('statics/home'))
} else {
router.get('/' + tpl, (req, res) => res.render('statics/' + tpl))
}
});
router.all('*', (req, res) => res.notFound());
module.exports = router;

Categories

Resources