What is the problem with router division in express? (React) - javascript

[app.js]
onCreate = async (event) => {
event.preventDefault();
const clubData = new FormData(event.target)
console.log(clubData);
const post = await axios.post('/club', {
method: 'POST',
body: {
name : 'name',
intro : 'intro'
}
}).then(response => {console.log(post)})
}
This is when the router is not division.
[server.js]
const express = require('express');
const path = require('path');
const engines = require('consolidate');
const bodyParser = require('body-parser');
const app = express();
const PORT = process.env.PORT || 4000;
app.use(express.static(path.join(__dirname, '..', 'public/')));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended:true}));
app.post('/club', function(req, res, next) {
res.send({ test: 'test'});
})
app.set('views', __dirname + '/views');
app.engine('html', engines.mustache);
app.set('view engine', 'html');
app.listen(PORT, () => {
console.log(`Check out the app at http://localhost:${PORT}`);
});
At this point, we were able to see data coming over from the developer window at Chrome.
However, after splitting the router, an error occurs.
[server.js]
const express = require('express');
const path = require('path');
const engines = require('consolidate');
const bodyParser = require('body-parser');
const app = express();
const PORT = process.env.PORT || 4000;
var clubRouter = require('./router/clubRouter.js');
app.use(express.static(path.join(__dirname, '..', 'public/')));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended:true}));
app.use('/club', clubRouter);
app.set('views', __dirname + '/views');
app.engine('html', engines.mustache);
app.set('view engine', 'html');
app.listen(PORT, () => {
console.log(`Check out the app at http://localhost:${PORT}`);
});
[clubRouter.js]
const router = require('express').Router();
const controller = require('../controller/clubController');
router.post('/club', function(req, res, next) {
res.send({ test: 'test'});
})
module.exports = router;
An error occurs at this time.
(POST http://localhost:3000/club 404 (Not Found))
I've now created a project with a react-app-create and webpack.config.Added the code to dev.js file.
devServer: {
port: 4000,
open: true,
proxy: {
"/": "http://localhost"
}
},
The code was also added to the package.json file .
"proxy": "http://localhost:4000"

The clubRouter is mounted on path /club
That means any /club* requests will be handled over to clubRouter
The clubRouter further registers a controller on path /club that sends the response { test: 'test'}
So,
The complete path would now be => /club/club
In your React app, try this change and it would work:
const post = await axios.post('/club/club', { ... })
If you think the path is not how you want, you can register the controller in the clubRouter as follows:
router.post('/', function(req, res, next) {
res.send({ test: 'test'});
})
That way, you would be able to get hit it with the old path as:
const post = await axios.post('/club', { ... })

Related

hbs.express4 is not a function

I was doing a nodejs based project using express and when I was adding partials to the server.js file. I got a type error: TypeError: hbs is not a function. I installed npm express-handlebars But still the same error
const express = require('express')
const http = require('http')
const path = require('path')
const hbs = require('express-handlebars')
const socket = require('socket.io')
const router = require('./routes/routes.js')
const app = express()
const server = http.createServer(app)
const session = require('express-session')
app.engine('hbs', hbs.express4({
defaultLayout: path.join(__dirname, 'views', 'layouts', 'default')
}))
app.use(express.json())
app.set('view engine', 'hbs')
app.use(express.urlencoded({ extended: false }))
app.use(express.static(path.join(__dirname, 'public')))
app.use('/', require('./routes/home'))
app.set('views', path.join(__dirname, 'views'))
server.listen(PORT, () => { console.log(`Server is running at http://localhost:${server.address().port}`) })

ExpressJS redirect index.html

JS,
I have an express app with some routes. When my router doesn't match any route it will display index.html instead of going to route '/*' and redirect to a specific route.
I don't understand why my router doesn't go to app.get('/*') because when I type https://my-domain.com I want to be redirect to https://my-domain.com/test?id=1.
Maybe I can do something with express-static but I don't know how.
And if I name my file home.html instead of index.html it's work perfectly.
Here is a small piece of my code :
const express = require('express');
const path = require('path');
const cors = require('cors');
const app = express();
const bodyParser = require("body-parser");
const ejs = require('ejs');
const csrf = require('csurf');
const port = 3080;
let csrfProtection = csrf({ cookie: true })
app.use(cors());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(csrfProtection);
app.engine('html', ejs.renderFile);
app.set('view engine', 'html');
app.use(function (err, req, res, next) {
if (err.code !== 'EBADCSRFTOKEN') return next(err)
res.status(403).json({error: "Invalid CSRF Token"});
})
app.post('/roles', csrfProtection, (req, res) => {
/*...*/
});
app.get('/test', csrfProtection, (req, res) => {
/*...*/
});
app.all('/*', csrfProtection, (req,res) => {
if(Object.keys(req.query).length == 0) {
res.redirect("https://my-domain.com/test?id=1");
}
res.render(path.join(__dirname + '/index.html'), {csrfToken: req.csrfToken()});
});
app.listen(port, () => {
console.log(`Server listening on the port::${port}`);
});
My files structure is :
home
static
css
js
index.html
index.js
At the request for https://my-domain.com, write res.redirect('/foo/bar'), where /foo/bar is the url you want to redirect to.
See Official Documentation For res.redirect(): http://expressjs.com/en/api.html#res.redirect

how to solve/fix this issue throw new TypeError('app.use() requires a middleware function') when starts the server in node js

I am facing this issue when trying to run server after create route and use route in app.js file.Please help me to resolve the error i have been stuck here for hours tried a lot of edits but its not working for me.
Here is my courseRoute.js
const express = require('express');
const router = express.Router();
const Course = require('../../models/Course');
const adminAuthMiddleware = require('../../middleware/adminAuthMiddleware');
router.get('/admin/view-course', adminAuthMiddleware, async (req, res) => {
try {
await Course.find((err, docs) => {
if (!err) {
res.render('admin-views/course/view_course', { courses: docs });
} else {
res.send('Error in retrieving Course list :' + err);
}
})
} catch (err) {
res.send(err);
}
});
This is my app.js
require('dotenv').config();
const express = require('express');
const cookieParser = require('cookie-parser');
const session = require('express-session');
const flash = require('connect-flash');
const bodyParser = require('body-parser');
const { check, validationResult } = require('express-validator');
const path = require('path');
require('./db/conn');
const courseRoute = require('./routes/admin routes/courseRoute');
const app = express();
const port = process.env.PORT || 3000;
const static_path = path.join(__dirname, "../public");
app.use(express.static(static_path));
app.use(express.json());
app.use(express.urlencoded({extended: false }));
app.set('view engine', 'ejs');
app.use(courseRoute);
app.listen(port, () => {
console.log(`Server is running at ${port}`);
});
Your courseRoute.js has no exports. In the last line add module.export = route;

Emitting socket.io events from express router and processing on server

I am trying to build a webchat app using node.js and express. I have a router file and a server file, together with some client files. I would like to emit a join event from the router and processing it on the server so the user can join the room. I did i like this
Server.js
const express = require('express');
const layout = require('express-layout');
const app = express();
var server = require('http').createServer(app);
var io=require('socket.io')(server);
const routes = require('./router')(io);
const bodyParser = require('body-parser');
var fs = require("fs");
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
const middleware = [
layout(),
express.static(path.join(__dirname, 'public')),
bodyParser.urlencoded(),
];
app.use(middleware);
app.use('/', routes);
app.use((req, res, next) => {
res.status(404).send("Sorry can't find that!");
});
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).send('Something broke!');
});
io.on('connect', onConnect);
function onConnect(socket) {
var contents = fs.readFileSync("./public/rooms.json");
let rooms = JSON.parse(contents);
socket.emit('parse',rooms);
socket.on('join',function (name, room) {
console.log(name+" "+ room);
socket.join(room);
socket.user=name;
socket.room=room;
})
}
Here I just initialize the io connection together with all the dependencies I use. I use const routes = require('./router')(io); to pass the io variable
router.js
const express = require('express');
const User= require("./public/classes/User");
const router = express.Router();
const {check, validationResult} = require('express-validator');
const {matchedData} = require('express-validator/filter');
var userlist=new Array();
router.get('/', (req, res) => {
res.render('index', {
data: {},
errors: {}
})
});
router.post('/enter', [
check('username')
.isLength({min: 1})
.withMessage('Username is required').trim() //implement personalized check
], (req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.render('index', {
data: req.body,
errors: errors.mapped()
})
}
const data = matchedData(req)
handleJoin(data);
});
return router;
//MOVE TO SUPPORT
function find(name) {
return 1;
}
function handleJoin (data){
if(find(data.username)){
const newUser= new User (data.username, data.room,"");
userlist.push(newUser);
io.emit('join',newUser.name,newUser.room);
}
};
};
The console should log the name and the choosen room but it doesn't. How do I process this?

Separating routes in Express

Edit #2
Got it, updated code
app.js
const express = require('express');
const bodyParser = require('body-parser');
const hbs = require('hbs');
const fs = require('fs');
var app = express();
// Server port
const port = process.env.PORT || 3000;
// Server starting message
app.listen(port, () => {
console.log(`Server is up on port ${port}`);
});
// Views directory established and handbars engine
hbs.registerPartials(__dirname + '/views/layouts')
app.set('view engine', 'hbs');
// static assets rendered
app.use(express.static(__dirname + '/public'));
// body-parser middleware
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())
// server.log setup middleware
app.use((req, res, next) => {
var now = new Date().toString();
var log = `${now}: ${req.method} ${req.url}`
console.log(log);
fs.appendFile('server.log', log + '\n', (err) => {
if (err) {
console.log('Unable to append to server.log');
}
});
next();
});
// Routes
const routes = require('./routes/routes');
app.use("/", routes);
// Get year for footer
hbs.registerHelper('getCurrentYear', () => {
return new Date().getFullYear()
});
Thank you everyone for your help!
Edit #1
I have added app.use("/", routes)" to my app.js but now when I test out my contact form and the mailer I get the following:
TypeError: Cannot read property 'name' of undefined
at router.post (/Users/benbagley/Code/poetry-out-loud/routes/routes.js:29:27)
at Layer.handle [as handle_request] (/Users/benbagley/Code/poetry-out-loud/node_modules/express/lib/router/layer.js:95:5)
at next (/Users/benbagley/Code/poetry-out-loud/node_modules/express/lib/router/route.js:137:13)
at Route.dispatch (/Users/benbagley/Code/poetry-out-loud/node_modules/express/lib/router/route.js:112:3)
at Layer.handle [as handle_request] (/Users/benbagley/Code/poetry-out-loud/node_modules/express/lib/router/layer.js:95:5)
at /Users/benbagley/Code/poetry-out-loud/node_modules/express/lib/router/index.js:281:22
at Function.process_params (/Users/benbagley/Code/poetry-out-loud/node_modules/express/lib/router/index.js:335:12)
at next (/Users/benbagley/Code/poetry-out-loud/node_modules/express/lib/router/index.js:275:10)
at Function.handle (/Users/benbagley/Code/poetry-out-loud/node_modules/express/lib/router/index.js:174:3)
at router (/Users/benbagley/Code/poetry-out-loud/node_modules/express/lib/router/index.js:47:12)
--
Original Question
I'm currently working on a node.js app and I'm trying to separate my app and routes into separate files.
Here is what I have so far
app.js
const express = require('express');
const bodyParser = require('body-parser');
const nodemailer = require('nodemailer');
const hbs = require('hbs');
const fs = require('fs');
const port = process.env.PORT || 3000;
var app = express();
hbs.registerPartials(__dirname + '/views/layouts')
app.set('view engine', 'hbs');
// body-parser middleware
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())
const routes = require('./routes/routes');
app.use((req, res, next) => {
var now = new Date().toString();
var log = `${now}: ${req.method} ${req.url}`
console.log(log);
fs.appendFile('server.log', log + '\n', (err) => {
if (err) {
console.log('Unable to append to server.log');
}
});
next();
});
app.use(express.static(__dirname + '/public'));
hbs.registerHelper('getCurrentYear', () => {
return new Date().getFullYear()
});
app.listen(port, () => {
console.log(`Server is up on port ${port}`);
});
routes.js
const express = require('express');
const router = express.Router();
// Routes
router.get('/', (req, res) => {
res.render('index.hbs', {
pageTitle: 'homepage'
});
});
router.get('/registration', (req, res) => {
res.render('registration.hbs', {
pageTitle: 'Registration'
});
});
router.get('/login', (req, res) => {
res.render('login.hbs', {
pageTitle: 'Login'
});
});
router.post('/send', (req, res) => {
const output = `
<p>You have a new contact request</p>
<h3>Contact Details</h3>
<br>
<ul>
<li>Name: ${ req.body.name }</li>
<li>Name: ${ req.body.email }</li>
</ul>
<h3>Message:</h3>
<p>${ req.body.message }</p>
`;
nodemailer.createTestAccount((err, account) => {
// create reusable transporter object using the default SMTP transport
let transporter = nodemailer.createTransport({
host: "smtp.mailtrap.io",
port: 2525,
auth: {
user: "xxxxxxx",
pass: "xxxxxxx"
}
});
// setup email data with unicode symbols
let mailOptions = {
from: `"${req.body.name}" <${req.body.email}>`, // sender address
to: 'xxxxxxxxx', // list of receivers
subject: 'New contact message', // Subject line
html: output // html body
};
// send mail with defined transport object
transporter.sendMail(mailOptions, (error, info) => {
if (error) {
return console.log(error);
}
console.log('Message sent: %s', info.messageId);
console.log('Preview URL: %s', nodemailer.getTestMessageUrl(info));
res.render('index', {
pageTitle: 'Thank you'
});
});
});
});
module.exports = router;
The current terminal output I'm receiving is
Server is up on port 3000
Tue Jan 09 2018 15:58:40 GMT+0000 (GMT): GET /
[nodemon] restarting due to changes...
[nodemon] starting `node app.js hbs, css`
Server is up on port 3000
and in the browser I'm getting
here is a screenshot of the file structure
Any help here would be appreciated.
I'm still new to this but I use the following on my base URL:
app.get('/', (req, res) => {
res.json('ready for your queries');
});
where
app = express() It's a simple code to let me know the server is running without doing anything with other services.
You should go for a tested solution. I like to use the express-generator. It creates a nice structure for you:
-bin
www
-config
-public
-javascripts
-stylesheets
-images
-routes
index.js
something.js
-views
index.ejs
something.ejs
app.js
bin/www holds your server-setting, app.js is where you load your config, your routes, your models if you are using a database. http://expressjs.com/en/starter/generator.html
You shouldn't have much trouble moving your code to this structure. Ask away if you have doubts.
Your code will be
app.js
const express = require('express');
const bodyParser = require('body-parser');
const nodemailer = require('nodemailer');
const hbs = require('hbs');
const fs = require('fs');
var app = express();
const port = process.env.PORT || 3000;
const routes = require('./routes/routes');
hbs.registerPartials(__dirname + '/views/layouts')
app.set('view engine', 'hbs');
// body-parser middleware
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())
router(app);
app.use((req, res, next) => {
var now = new Date().toString();
var log = `${now}: ${req.method} ${req.url}`
console.log(log);
fs.appendFile('server.log', log + '\n', (err) => {
if (err) {
console.log('Unable to append to server.log');
}
});
next();
});
app.use(express.static(__dirname + '/public'));
hbs.registerHelper('getCurrentYear', () => {
return new Date().getFullYear()
});
app.listen(port, () => {
console.log(`Server is up on port ${port}`);
});
routes.js
module.exports = function (app) {
app.get('/', (req, res) => { res.render('index.hbs', { pageTitle: 'homepage' }); });
router.get('/login', (req, res) => { res.render('login.hbs', { pageTitle: 'Login' }); });
..... Remaining function
}

Categories

Resources