Cannot read property 'Image' of undefined error on Nodejs - javascript

I was Trying to make a shopping cart. i was making admin panel in which i need to submit the image for adding product. After creating the Form
<section>
<div class="container mt-4">
<div class="row">
<div class="col-md-6">
<h2 class="text-cnter">Add Product</h2>
<form action="/admin/add-product" method="POST" enctype="multipart/form-data">
<label for="">Name</label>
<input type="text" name="Name" class="form-control">
<label for="">Category</label>
<input type="text" name="Category" class="form-control">
<label for="">Price</label>
<input type="text" name="Price" class="form-control">
<label for="">Description</label>
<input type="text" name="Description" class="form-control">
<label for="">Image</label>
<input type="file" class="form-control">
<button class="btn btn-success mt-4" type="submit">Submit </button>
</form>
</div>
</div>
</div>
</div>
</section>
In admin.js file ( where router of admin )
router.get('/add-products',function(req,res){
res.render('admin/add-products')
});
// router.post('/add-product',function (req,res) {
// console.log('Got it')
// });
router.post( "/add-product", function( req, res ) {
console.log(req.body)
console.log(req.file.Image)
});
module.exports = router;
app.js file
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var hbs = require('express-handlebars');
var fileupload =require('express-fileupload');
var bodyParser = require('body-parser');
var userRouter = require('./routes/user');
var adminRouter = require('./routes/admin');
const {allowInsecurePrototypeAccess} = require('#handlebars/allow-prototype-access')
var multipart = require('connect-multiparty');
var multipartMiddleware = multipart();
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'hbs');
//Layout Directory Set
app.engine('hbs',hbs.engine({ extname:'hbs' , defaultLayout:'layout',layoutsDir:__dirname+'/views/layout/',partialsDir:__dirname+'/views/partials'}));
app.engine('handlebars', hbs.engine({
handlebars: allowInsecurePrototypeAccess(hbs)
}));
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(fileupload());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', userRouter);
app.use('/admin', adminRouter);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
after running with nodemon giving submit button shows
Cannot read property 'Image' of undefined
TypeError: Cannot read property 'Image' of undefined
Btw i was just started on nodejs .Thats why i dont know more about it.

You might want to check this line in your admin.js file:
console.log(req.file.Image)
Based on the error message req.fileis undefined and therefor it can't read Image.
The reason is, that express needs extra middleware to correctly handle multipart/form-data. Check out Multer. This should help you getting all the parts of your form including the file(s).
Also be aware that your file input does not have a same. So you definitely can't find it with Image.

Seems like req.file is undefined, so it can't read the property Image of undefined.

try changing this. first provide a name to your input file
<label for="">Image</label>
<input type="file" name = "img" class="form-control">
try getting the file then using
router.post( "/add-product", function( req, res ) {
console.log(req.body)
console.log(req.files.img)
});

Related

can't POST my form in express js application

I am trying to build my first app independently but I cannot go through that problem. I will be very grateful if someone helps me understand where the problem is. After click submit button I am getting an error Cannot POST /. I suspect that a mistake i trivial and this is annoying for me. In my opinion problem is in my route file.
Here is my html form (wrote in ejs):
<%- include('includes/start.ejs') %>
<%- include('includes/navbar.ejs') %>
<div class="container">
<p>Here you can create your Tournament!</p>
<form class="form" action="/" method="POST">
<label>Discypline:</label><br>
<input type="text" name="discipline" placeholder="E.G. Chess"><br><br>
<label for="lname">Tournament type:</label><br>
<select name="type">
<option value="Bracket Tournament">Bracket Tournament</option>
<option value="League Tournament">League Tournament</option>
</select><br><br>
<label>Description of Tournament:</label><br>
<textarea name="description" rows="4" cols="50"></textarea><br><br>
<input type="submit" value="Submit"><br>
</form>
<%- include('includes/end.ejs') %>
</div>
Here is my route file:
const express = require('express');
const router = express.Router();
const bodyParser = require('body-parser');
router.use(bodyParser.urlencoded({extended: false}));
router.use(bodyParser.json());
const Tournament = require('../models/tournament.js')
router.get('/creator', (req, res, next) => {
res.render('../views/creator.ejs');
});
router.post('/creator', (req, res, next) => {
//const tournament = new Tournament()
console.log(req.body.discipline);
return;
});
module.exports = router;
And here is my app code:
const express = require('express');
const app = express();
const path = require('path');
const homeRouter = require('.//routes/home.js');
const creatorRouter = require('.//routes/creator.js');
app.set('view engine', 'ejs');
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', homeRouter);
app.use('/', creatorRouter);
app.listen(3000);
Thanks for a help.
Best regards.

Nodejs post method - req.body.variable undefined

I have the following App.js:
var express = require('express'),
app = express(),
engines = require('consolidate'),
MongoClient = require('mongodb').MongoClient,
assert = require('assert'),
bodyParser = require('body-parser')
app.engine('html', engines.nunjucks);
app.set('view engine', 'html');
app.set('views', __dirname + '/views');
app.use(bodyParser.urlencoded({ extended : true }));
// app.use(bodyParser.urlencoded());
// app.use(bodyParser.json());
app.post('/insert_movie', function (req, res) {
var movieName = req.body.movie_name;
console.log(movieName);
});
// No route matching:
app.use(function (req, res) {
res.sendStatus(404);
});
var server = app.listen(3000, function () {
var port = server.address().port;
console.log('Express server listening on port %s.', port);
});
My html page:
<h1> Add new movies</h1>
<form action="/insert_movie" method="POST">
<input type="text" id="movie_name">
<input type="text" id="movie_year">
<input type="text" id="movie_imdb">
<input type="submit" value="Submit" />
</form>
When I enter values into the text boxes and press submit, my post method is hit ('/insert_movie'). However movieName is undefined not only that but req.body is {}
Can someone explain to me what I'm doing wrong here as I've gone through many solutions on this website however they're all pointing the body parser being incorrectly setup, I've tried the following:
app.use(bodyParser.urlencoded({ extended : true }));
app.use(bodyParser.urlencoded());
app.use(bodyParser.json());
Neither of these fix my issue.
You need to add name attribute to the input elements. That's one of the things your body-parser library needs to parse the form.
<h1> Add new movies</h1>
<form action="/insert_movie" method="POST">
<input type="text" name="movie-name" id="movie_name">
<input type="text" name="movie-year" id="movie_year">
<input type="text" name="movie-url" id="movie_imdb">
<input type="submit" value="Submit" />
</form>
try to use this
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({
limit: '500mb',
extended: true,
parameterLimit: 50000
}));
app.use(expressValidator());
app.use(bodyParser.json());
use multer middle ware for req.body
var app = require('express')();
var multer = require('multer);
var upload = multer().any();
//multer().any() upload both array and file
//add the multer middle ware in your router
app.post('/insert_movie',upload, function (req, res) {
var movieName = req.body.movie_name;
console.log(req.body);
console.log(movieName);
});
you can see the official npm blog
https://www.npmjs.com/package/multer

req.body is undefined - nodejs

Here is my html:
<form action='/new' method='POST' >
<span>pool name: </span>
<input type="text" name="name" />
<input type="hidden" name="imageSrcList" />
<button type='submit' >Create new</button>
</form>
And here is the relevant JS:
var app = express()
app.use(fileUpload());
app.set('view engine', 'ejs')
app.use(express.static(__dirname + '/views'));
app.post('/new', (req, res) => {
console.log(req.body.name);
})
The console reads out:
TypeError: Cannot read property 'name' of undefined
I have tried with console.log(req.body) and this also is undefined.
Thanks in advance!
You're missing the body-parser middleware which is necessary to have req.body set to a value. Express doesn't come with this by default and will need to be installed via NPM npm i --save body-parser
const bodyParser = require('body-parser')
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({extended: true}))

node.js won't start - error 404 - not found

I'm a big newb at node.js so please don't start bashing me just yet. I'm using the express framework and i am trying to build a simple application to display as html.
Here's the basic app.js
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var routes = require('./routes/index');
var users = require('./routes/users');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
//app.use('/', routes);
//app.use('/users', users);
app.use('/registration', require('./routes/registration'));
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handlers
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
});
});
}
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});
app.listen(3000, function () {
console.log("Poslusam na portu 3000!");
});
module.exports = app;
Here's the regisration.js code i'm trying to display
var express = require('express');
var router = express.Router();
var db = require('../node_modules/nyModule/db.js');
var app = express();
var users = db.getUsers();
router.get('/', function (req, res) {
res.render('registration');
});
router.post('/', function (req, res) {
var registration = JSON.stringify(req.body);
console.log(registration);
var o = JSON.parse(registration);
console.log("Login: " + o.email);
baza.addRegistration(o);
res.redirect('/');
});
module.exports = router;
and here's the registration.html
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
</head>
<body>
<h2>App</h2>
<h3>Registration/h3>
<form method="post">
<label>Name: </label><br />
<input type="text" name="name" id="name" /><br /><br />
<label>LastName: </label><br />
<input type="text" name="lname" id="lname" /><br /><br />
<label>Elektronski naslov:</label><br />
<input type="text" name="email" id="email" /><br /><br />
<label>Username: </label><br>
<input type="text" name="username" id="username" /><br> <br>
<label>Password</label><br>
<input type="password" name="password" id="password" /><br>
<input type="submit" value="Register" />
</form>
</body>
</html>
This is the result that i get on localhost:3000
Please help me
update
Line: 20
You should set view engine as html file.
Insert this code into app.js file.
app.set('views', __dirname + '/views');
app.engine('html', require('ejs').renderFile);
app.set('view engine', 'html');

ForbiddenError: invalid csrf token, express js

I've tried to get csurf to work but seem to have stumbled upon something. The code so far looks like this:
index.ejs
<form method="post" action="/">
<input type="hidden" name="_csrf" value="{{csrfToken}}">
.
.
</form>
Where you insert password and username in the form.
app.js
var express = require('express');
var helmet = require('helmet');
var csrf = require('csurf');
var path = require('path');
var favicon = require('serve-favicon');
var flash = require('connect-flash');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var session = require('express-session');
var routes = require('./routes/index');
var users = require('./routes/users');
var profile = require('./routes/profile');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
//Security shyts
app.use(helmet());
app.use(helmet.xssFilter({ setOnOldIE: true }));
app.use(helmet.frameguard('deny'));
app.use(helmet.hsts({maxAge: 7776000000, includeSubdomains: true}));
app.use(helmet.hidePoweredBy());
app.use(helmet.ieNoOpen());
app.use(helmet.noSniff());
app.use(helmet.noCache());
// rest of USE
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(session({secret: 'anystringoftext', saveUninitialized: true, resave: true, httpOnly: true, secure: true}));
app.use(csrf()); // Security, has to be after cookie and session.
app.use(flash());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', routes);
app.use('/users', users);
app.use('/profile', profile);
// catch 404 and forward to error handler
app.use(function (req, res, next) {
res.cookie('XSRF-TOKEN', req.csrfToken());
res.locals.csrftoken = req.csrfToken();
next();
})
//app.use(function(req, res, next) {
// var err = new Error('Not Found');
// err.status = 404;
// next(err);
//});
// error handlers
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
});
});
}
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});
module.exports = app;
Where I've put csrf after session and cookie parser.
index.js
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', { title: 'some title',message: '' });
});
router.post('/',function(req,res){
// Where I have a bunch of mysql queries to check passwords and usernames where as if they succeed they get:
res.redirect('profile');
// Else:
res.redirect('/');
});
What I get after submiting the form, no matter if I insert the correct username and password or not I still get the same error:
invalid csrf token
403
ForbiddenError: invalid csrf token
Also I want add that I've been working with node for about 2 weeks, so there is still alot I need to learn probably.
{{csrfToken}} isn't an EJS construction, so it's not expanded at all and is probably sent literally to your server.
This should work better:
<input type="hidden" name="_csrf" value="<%= csrfToken %>">
The middleware is setting csrftoken though, with lowercase 't', where the template expects an uppercase 'T':
res.locals.csrftoken = req.csrfToken(); // change to `res.locals.csrfToken`
You also generate two different tokens, which is probably not what you want. Store the token in a variable and reuse that:
app.use(function (req, res, next) {
var token = req.csrfToken();
res.cookie('XSRF-TOKEN', token);
res.locals.csrfToken = token;
next();
});
And lastly, you probably have to move your middleware to before the route declarations, otherwise it won't be called:
app.use(function (req, res, next) {
var token = req.csrfToken();
res.cookie('XSRF-TOKEN', token);
res.locals.csrfToken = token;
next();
});
app.use('/', routes);
app.use('/users', users);
app.use('/profile', profile);
My Express version is 6.14.4. The most important matter is you have to maintain the order of the line.
App.js
var cookieParser = require('cookie-parser');
var csrf = require('csurf');
var bodyParser = require('body-parser');
//order of bellow lins is very important
app.use(bodyParser.urlencoded({ extended: false }))
app.use(cookieParser())
app.use(csrf({ cookie: true }))
routes/index.js
var express = require('express');
var router = express.Router();
router.get('/user/signup', function(req, res, next){
console.log("csruf: "+req.csrfToken());
res.render('user/signup', { csrfToken: req.csrfToken() });
});
router.post('/postuser', function(req, res, next){
//res.render('/');
res.redirect('/');
});
view file
<form action="/postuser" method="POST">
<div class="form-group">
<label for="email"> E-Mail</label>
<input type="text" id="email" name="email" class="form-control">
</div>
<div class="form-group">
<label for="password">Password</label>
<input type="password" id="password" name="password" class="form-control">
</div>
<input type="hidden" name="_csrf" value="{{csrfToken}}">
<button type="submit" class="btn btn-primary">Sign Up</button>
</form>

Categories

Resources