Failed to load resource: the server responded with a status of 404 (Not Found) on routing - express

I am trying to route in my project. I want that on clicking connect button the rooms page should get rendered. Home page is working fine but as soon I as click connect it shows Cannot GET /rooms/0b2636b5-c254-47f4-ade8-9e6b745a96d1.The code works fine when instead of routing to rooms it is on root url.
I am new to web development and I tried reading other questions on similar problem but couldn't understand.
Server side(Server.js):
const express = require('express');
const app = express();
const server = require('http').Server(app);
const { v4: uuidV4 } = require('uuid');
const io = require('socket.io')(server);
const { ExpressPeerServer } = require('peer');
const peerServer = ExpressPeerServer(server, {
debug: true
});
app.use('/peerjs', peerServer);
app.set('view engine', 'ejs');
app.use(express.static('public'));
app.get('/', (req, res) => {
res.render('home');
})
app.get('/rooms', (req, res) => {
res.redirect(`/rooms/${uuidV4()}`);
})
app.get('/rooms:room', (req, res) => {
res.render('room', { roomId: req.params.room })
})
server.listen(3000);
Client Side(script.js)
const socket = io('/rooms');
const videoGrid = document.getElementById('video-grid');
var peer = new Peer(undefined, {
path: '/peerjs',
host: '/rooms',
port: '3000'
})
Navigation bar on home.ejs
<nav class="nav">
<li class="nav-link">
Connect
</nav>
room.ejs
<script>
const ROOM_ID = "<%=roomId%>"
</script>
<script src="/socket.io/socket.io.js" defer ></script>
<script src="script.js" defer></script>
Structure of file
public
-script.js
views
-home.ejs
-room.ejs
server.js

You're really close to it, just 1 mistake in this block:
app.get('/rooms:room', (req, res) => {
res.render('room', { roomId: req.params.room })
})
It should be:
app.get('/rooms/:room', (req, res) => {
res.render('room', { roomId: req.params.room })
})
Express documentation page here in case you need it (section Route parameters).

Related

Next js custom server problem when deployed to cloud

I've created a next js custom server feature using express
Everything works fine on localhost but when deployed to google cloud
only the routes from page/api directory is working.
the /test route is not working
Server
const express = require('express')
const next = require('next')
const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()
app.prepare().then(() => {
const server = express()
server.get('/test', (req, res) => {
res.send('This is a test page')
})
server.get('*', (req, res) => {
return handle(req, res)
})
server.listen(3000, (err) => {
if (err) throw err
console.log('Now serving on port 3000')
})
})
package.json
"start": "NODE_ENV=production node server.js",

Can't receive a response message when using proxy-middleware between react ui and express backend

I see that the request sent from the ui created using React is forwarded to the backend, but I can't get the response from the ui. There may be details that I missed as I am very new to these issues, thanks in advance :)
//react Login.js
function Login() {
const fetch = actions.fetchUser();
async function handleSubmit() {
try {
fetch();
} catch (err) {
console.error('err', err);
}
}
export default Login;
//index.js
import axios from 'axios';
export const fetchUser = () => async () => {
await axios.get('/api/login');
};
//setupProxy.js
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function (app) {
app.use(
['/api'],
createProxyMiddleware({
target: 'http://localhost:5000',
}),
);
};
//express app.js
const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');
const app = express();
const port = 5000;
app.use(cors());
app.use(bodyParser.json());
require('./routes/login')(app);
app.listen(port, () => {
console.log(`Example app listening on port ${port}`)
})
// espress login.js
module.exports = app => {
app.get('/api/login', (req, res) => {
console.error('express login');
res.send('login');
});
First of all, do not mix cjs and mjs import/exports.
second of all, you export your middleware but never register/use it. At least your code does not show that part.
Here is very minimal example how you can proxy your react UI via express.
const express = require('express');
const proxy = require('express-http-proxy');
const app = express();
app.get('/api', (req, res) => {
res.send({my: 'data'});
});
// register other routes here
app.use(proxy('http://127.0.0.1:3000'));
app.listen(5000, '0.0.0.0', () => {
console.log('Server is running at http://127.0.0.1:5000');
});
React app content will be available on http://127.0.0.1:5000 with your routes.
And http://127.0.0.1:5000/api will be your express route.
Note: I assume your react app runs on the port 3000

i18next dropdown select without reactjs

I need to create a dropdown in order to select languages in the website. I only use nodejs not react. How can I create it? My codes are at the below.enter image description here
const express = require('express');
const app = express();
const ejs = require('ejs');
const i18next = require('i18next');
const Backend = require('i18next-fs-backend');
const i18nextMiddleware = require('i18next-http-middleware');
i18next
.use(Backend)
.use(i18nextMiddleware.LanguageDetector)
.init({
fallbackLng: 'tr',
lng: 'tr',
backend: {
loadPath: './translate/{{lng}}.json',
},
});
app.use(i18nextMiddleware.handle(i18next));
app.use(express.json());
app.set('view engine', 'ejs');
const stdI18next = { t: i18next.t.bind(i18next.t) };
app.get('/', (req, res) => {
res.render('index', stdI18next);
});
app.get('/test', (req, res) => {
res.render('test', stdI18next);
});

Expressjs + ejs and a tags href urls not working with subdirectory routes

I don't understand few things here for sure :)
Basic app structure as app.js file as:
const express = require('express');
const port = process.env.Port || 5000;
const app = express();
const path = require('path');
const mainRoute = require( path.join(__dirname, 'src/routes/mainRoute'));
app.use(function (req, res, next) {
res.header('Cache-Control', 'public, max-age=3600');
next();
});
app.use(express.static('public', {
maxAge: '1d',
}));
app.set('views', path.join(__dirname, 'src/views'));
app.set('view engine', 'ejs');
app.use('/', mainRoute);
app.get('*', function(req, res){
res.status(404).send('404???')
});
app.listen( port, () => console.log(`Listening on port`, port ));
As well as a basic structure route.js file as:
const express = require('express');
const mainRoute = express.Router();
mainRoute.get('/', async (req, res) => {
res.render('page', {url: 'pageone', title: 'page 1'});
});
mainRoute.get('/pageone', async (req, res) => {
res.render('page', {url: 'pagetwo', title: 'page 2'});
});
mainRoute.get('/pagetwo', async (req, res) => {
res.render('page', {url: 'pageone', title: 'page 1'});
});
module.exports = mainRoute;
And on page.ejs template something simple as:
<a href="/<%= url %>">
<%= title %>
</a>
<hr />
<a href="/">
home
</a>
Then adding a second route with the same route and page.ejs
app.use('/loc', mainRoute);
app.use('/sub', mainRoute);
So, now, the issue is when I load the URL:
http://localhost:5000/sub
then the links on the page render the view source href="/pageone" so, when I click on those link the page goes to a http://localhost:5000/ is not keeping the '/sub' set on the main route
For instance, in angular2 I can keep all the links and respect the sub folder with base url tag set on the index
But seems not the case on expressjs
How do I keep all links on the page to the /sub or /loc path? without rendering or adding those to the ejs template?
I mean, having the links relative to the route directory?
You can use req.baseUrl to get the path on which the router was mounted. You can pass it to the page.ejs view and construct the URLs.
// mainRoute.js
mainRoute.get('/', async (req, res) => {
res.render('page', { url: 'pageone', title: 'page 1', baseUrl: req.baseUrl })
})
mainRoute.get('/pageone', async (req, res) => {
res.render('page', { url: 'pagetwo', title: 'page 2', baseUrl: req.baseUrl })
})
mainRoute.get('/pagetwo', async (req, res) => {
res.render('page', { url: 'pageone', title: 'page 1', baseUrl: req.baseUrl })
})
<!-- page.ejs -->
<a href="<%= `${baseUrl}/${url}` %>">
<%= title %>
</a>
<hr />
<a href="<%= baseUrl %>">
Home
</a>

fetch POST request is pending (sending data from registration form)

I know that similar questions have already been here, but I didn't find anything for my problem.
I am creating project using [Webpack-Express-Pug-VanillaJS] stack of technologies.
I'm trying to make POST-request to send formData to '/api/users' using fetch a push data to array in my express file, but its only pending...
What kind of problems it can be?
client-side code
document.addEventListener('DOMContentLoaded', () => {
async function postData(url, data) {
try {
console.log('addEventListener works!')
const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
})
console.log('fetch works!')
return await response.json()
} catch(e) {
console.warn('Error',e.message)
}
}
const forms = document.getElementsByTagName('FORM');
for (let i = 0; i < forms.length; i++) {
forms[i].addEventListener('submit', function(e) {
console.log(forms[i])
e.preventDefault();
let formData = new FormData(this);
formData = Object.fromEntries(formData);
console.log(formData) return object like {name:'Zhanna', age:25, email:'123zhanna#gmail.com'}
postData('/api/users', formData).then(data => console.log('Successful!'))
})
}
})
server-side
const path = require('path')
const express =require('express')
const webpack = require('webpack')
const bodyParser = require('body-parser')
const users = require('../routes/userInfo')
import webpackDevMiddleware from 'webpack-dev-middleware'
import webpackHotMiddleware from 'webpack-hot-middleware'
import config from '../../webpack.dev.config.js'
import { v4 } from 'uuid';
const PORT = process.env.PORT || 8080
const app = express(),
compiler = webpack(config)
app.use(users.router);
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(express.json());
app.set('views', path.join(__dirname, "views"));
app.set('view engine', 'pug');
app.locals.basedir = __dirname;
app.use('/assets',express.static(path.join(__dirname,'assets')))
app.use(webpackDevMiddleware(compiler, {
publicPath: config.output.publicPath
})
)
app.use(webpackHotMiddleware(compiler))
app.get('/registration', (req,res)=> {
res.status(200).render('registration')
})
app.get('/login', (req,res)=> {
res.status(200).render('signIn')
})
app.get('/', (req, res) => {
res.status(200).render('index')
}
)
app.get('/api/users', (req,res)=> {
res.status(200).json(users.list)
})
app.post('/api/users', (req,res)=> {
const user = {...req.body, id:v4()}
users.list.push(user)
console.log('Data was sent')
res.status(201).json(user)
})
app.listen(PORT, () => {
console.log(`App listening to ${PORT}....`)
console.log('Press Ctrl+C to quit.')
})
And in my console there is only 3 logs:
addEvent listener works!
<form class="registration--form" id="send-form">...<form>
3.{name: "Zhanna", surname: "Kaymedenova", gender: "female", brth: "07.01.1994", email: "zh.kaymed#gmail.com"}