I have simply express server:
const express = require('express');
const exphbs = require('express-handlebars');
const path = require('path');
const bodyparser = require('body-parser');
const app = express();
const hbs = exphbs.create({
defaultLayout: 'main',
extname: 'hbs'
});
const _PORT = process.env.PORT || 80;
app.engine('hbs', hbs.engine);
app.set('view engine', 'hbs');
app.set('views', 'views');
app.use(bodyparser.urlencoded({ extended: false }));
app.use(bodyparser.json({ type: 'application/*+json' }));
app.use(express.static(path.join(__dirname, 'public')));
app.use(require('./routers/login'));
serverStart();
async function serverStart(){
try{
app.listen(_PORT);
console.log('[SERVER] Server is listening port ' + _PORT + ' now.');
}catch(error){
console.log(error);
}
}
And simply router:
const { Router } = require('express');
const router = Router();
router.get('/', async (req, res) => {
res.render('login', {
title: 'main page'
});
});
router.post('/', async (req, res) => {
console.log(req.body);
});
module.exports = router;
Why 'req.body' is always empty?
I tried to send POST query from "Postman", but it isn't work.
It's working only with x-www-form-urlencoded query, but I want to send json query.
P.S. Sorry for my english.
UPD: postman screenshot
link
I've been try your code and it's working fine, you only have to change your code:
app.use(bodyparser.json({ type: 'application/*+json' }));
With this code below:
app.use(bodyparser.json({ type: 'application/json' }));
Note: If you're use the latest version of express, then you should not to install body-parser, Because body-parser is already included.
So, you can use this code below:
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
I hope it can help you.
Related
I'm building a server with Node and Express, using handlebars as views. My controller contains the system logic functions, which receive the request and response objects as parameters and my Route, only makes the connection between the route and the controller. But I am not able to see the error to generate this error in the title.
My controller.js:
const router = express.Router();
exports.home = (req, res) => {
res.render('home', { entries: entries });
};
exports.Form = (req, res) =>{
res.render('form')
};
exports.FormFetch = (req, res) =>{
res.render('form-fetch')
};
My app.js:
const express = require('express');
const handlebars = require('express-handlebars');
const app = express();
app.engine('.hbs', handlebars.engine({
defaultLayout: 'main',
extname: '.hbs',
}));
app.set('view engine', '.hbs')
app.use(express.urlencoded({ extended: false }));
app.use(express.json());
var userRoute = require('./routes')
app.get('/', userRoute)
app.use('/new-entry', userRoute)
app.use('/new-entry-fetch', userRoute)
app.listen(3000, () =>{
console.log('Ok')
});
My routes.js:
const express = require('express');
const controller = require('./controllers/controllers');
const app = express();
const entries = [];
app.get('/', (req, res) => {
res.render(controller.home, { entries: entries });
});
app.get('/new-entry', (req, res) => {
res.render(controller.Form);
});
app.get('/new-entry-fetch', (req, res) => {
res.render(controller.FormFetch);
});
app.post('/new-entry', (req, res) => {
entries.push({
title: req.body.title,
content: req.body.body,
published: new Date()
});
res.redirect(303, '/');
});
module.exports = app
I created a simple application. Until I split the application code into an MVC template, everything worked. Below I present the code of my application. After going to localhost:3000/add-service you will see Cannot Get /add-service message.
Where is the problem that I unfortunately cannot solve?
app.js
const express = require('express');
const path = require('path');
const bodyParser = require('body-parser');
const expressLayouts = require('express-ejs-layouts');
const adminRoutes = require('./Routes/admin');
const shopRouters = require('./Routes/shop');
const app = express();
app.use(expressLayouts);
app.set('view engine', 'ejs');
app.set('views', './views');
app.use(bodyParser.urlencoded({ extended: false }));
app.use(express.static(path.join(__dirname, 'public')));
app.use('/add-service', adminRoutes);
app.use(shopRouters);
app.use('/', (req, res, next) => {
res.status(404).render('./pages/404', {
title: '404 Page Not Found',
path: '',
});
});
app.listen(3000);
admin.js - this is my router file
const express = require('express');
const router = express.Router();
const bikesController = require('../controllers/bikes');
router.get('/add-service', bikesController.getAddBike);
module.exports = router;
bikes.js - this is my controller
const bikes = [];
exports.getAddBike = (req, resno) => {
res.render('../views/pages/add-service', {
path: 'pages/add-service',
title: 'Add in Service',
});
};
exports.postAddBike = (req, res) => {
bikes.push({ title: req.body.bikeModel });
res.redirect('/');
};
exports.getBikes = (req, res) => {
res.render('./pages/shop', {
model: bikes,
docTitle: 'List of Bikes',
path: '/',
title: 'Main Page',
});
};
App Tree
app.use('/add-service', adminRoutes);
You've mounted adminRoutes at /add-service
router.get('/add-service', bikesController.getAddBike);
The only end point that service provides is /add-service
Combine them and you have the URL: /add-service/add-service, which isn't what you are asking for.
The point of the router is that it doesn't need to know about the URLs above where it sits.
The router should just be dealing with its own section of the URL hierarchy:
router.get('/', bikesController.getAddBike);
I write some routing on Express js and i have 2 routers here. There are /posts and /posts/:id . And when I try to get result by ID I have an error : my static file app.css was not processed by express.static() and come to req.url , due to it my code doesn't work and give me undefined. So pug view renders , but thus it is cant get css
There is my main file : server.js
const bodyParser = require('body-parser');
const app = express();
app.set('view engine', 'pug');
app.use('/public', express.static(__dirname + '/public'));
app.use(bodyParser.urlencoded({extended: false}));
app.use(bodyParser.json());
app.get('/', (req, res)=>{
res.render('index')
})
app.use('/posts', require('./routes/posts.js'))
app.listen(3000)
This is my posts.js Router
const bodyParser = require('body-parser');
const router = express.Router();
const posts = require('../data/posts.json');
router.get('/', (req, res)=>{
res.render('posts', {
posts: posts
})
});
router.get('/:id', (req ,res)=>{
console.log(req.url);
const post = posts.find(post=> post.id == req.params.id);
console.log(post);
res.render('post', {
title: post.title,
content: post.content
})
})
module.exports = router
Here is an error and results of logs
/2
{ title: 'Посадка помидоров',
content: 'Как я посадила помидоры и они не выросли',
id: 2 }
/app.css
undefined
TypeError: Cannot read property 'title' of undefined
Im using express-ejs-layout for my project. my project has routing. I want use different layout for different res queries. for example if query is: www.xxx.com/a, use LayoutA.ejs, if query is: www.xxx.com/b, use LayoutB.ejs. My index.js part code is:
...
app.set('view engine', 'ejs');
app.set('views', path.join(__dirname, '/app_server/views'));
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(ejsLayout);
app.use('/public', express.static(path.join(__dirname, 'public')));
require('./app_server/routes/routeManager')(app);
...
how can I?
I've just solve problem myself. I'll write for friends who face to same problem.
app.get('/a', function(req, res) {
res.render('view', { layout: 'LayoutA' });
});
app.get('/b', function(req, res) {
res.render('view', { layout: 'LayoutB' });
});
This is what I do:
First, I set a default layout
// app.js
app.set('layout', 'layouts/front') // assuming it's inside the 'views' directory
Then, I use middlewares for separate Router instances:
// app.js
app.use('/admin', AdminRoutes);
In my AdminRoutes.js:
// AdminRoutes.js
const router = express.Router();
router.use((req, res, next) => {
// changing layout for my admin panel
req.app.set('layout', 'layouts/admin');
next();
});
router.get('/', (req, res) => {
res.render('admin/index'); // will use admin layout
});
const path = require('path')
const express = require('express');
const app = express();
app.set('view engine', 'ejs');
app.set('views', path.join(__dirname, 'views'));
app.set('layout', 'layoutsA', 'layoutsB');
const router = require("express").Router();
const expressLayouts = require("express-ejs-layouts");
// user router
router.use(expressLayouts)
router.get('/, (req, res) =>{
res.render("user", {layout: "layoutsA"})
})
const router = require("express").Router();
const expressLayouts = require("express-ejs-layouts");
// post router
router.use(expressLayouts)
router.get('/, (req, res) =>{
res.render("user", {layout: "layoutsB"})
})
app.js:
var express = require('express');
var path = require('path');
var bodyParser = require('body-parser');
var routes = require('./routes/index');
var person = require('./routes/person');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', routes);
app.use('/person', person);
module.exports = app;
routes/person.js:
var express = require('express');
var bodyParser = require('body-parser');
var urlencodedParser = bodyParser.urlencoded({ extended: false });
var router = express.Router();
/* GET page. */
router.get('/', function (req, res) {
res.render('person', {
message: 'Person works'
});
});
router.post('/', urlencodedParser, function (req, res) {
res.send('Thank you!');
console.log(req.body.firstname);
console.log(req.body.lastname);
});
views/person.pug:
extends layout
block content
h1 Welcome #{id}
p= message
br
h2= qstr
br
form(method='post', action='/person')
label First name
input#firstname(type='text')
br
label Last name
input#lastname(type='text')
input(type='submit', value='Submit')
Questions:
1) Is it necessary in every route to add?:
var bodyParser = require('body-parser');
var urlencodedParser = bodyParser.urlencoded({ extended: false });
2) Why do I get this:
1.You don't need to use body-parser in every route. Body-parser is a middleware which is used to obtain data from application/x-www-urlencoded content type. So if you're sure sure that data you will get in your body is not x-www-urlencoded type, you don't need to use it.
2.Please check if you are passing the data in post request. You can use chrome extension postman to form any kind of query.