Cannot read property 'path' of undefined node js multer - javascript

i am building a app that lets the user create a camp and than edit it.Recently i added the upload image feature it works fine with the create route but on the edit one it doesnt let the user leave it blank cause if that happens it give the undefined error.Do you have anyideas how i can fix this.I dont have much experience so any help would be welcomed.
This is the js code
var express = require("express");
var router = express.Router({mergeParams:true});
var Campground = require("../models/campground");
var middleware=require("../middleware");
const multer = require('multer');
const storage = multer.diskStorage({
destination: function(req, file, cb) {
cb(null, './uploads/');
},
filename: function(req, file, cb) {
const now = new Date().toISOString(); const date = now.replace(/:/g, '-'); cb(null, date + file.originalname);
}
});
const fileFilter = (req, file, cb) => {
// reject a file
if (file.mimetype === 'image/jpeg' || file.mimetype === 'image/png') {
cb(null, true);
} else {
cb(null, false);
}
};
const upload = multer({
storage: storage,
limits: {
fileSize: 1024 * 1024 * 5
},
fileFilter: fileFilter
});
//edit
router.get("/:id/edit",middleware.checkCampgroundOwnership, function(req,res){
Campground.findById(req.params.id,function(err,foundCampground){
res.render("campgrounds/edit",{campground :foundCampground});
});
});
router.put("/:id",upload.single('image'),middleware.checkCampgroundOwnership, function(req,res){
var name = req.body.name;
var image = req.file.path;
var description = req.body.description;
var price = req.body.price
var upCampground = {price:price,name:name, image: image ,description:description};
Campground.findByIdAndUpdate(req.params.id,upCampground,function(err,updatedCamp){
if(err){
res.redirect("/campgrounds");
}
else{
res.redirect("/campgrounds/"+req.params.id);
}
})
});
This is the ejs one
<%-include ('../partials/header') %>
<div class="container">
<h1 style="text-align: center;"> Edit a <%= campground.name%></h1>
<div style="width: 30%; margin: 25px auto;">
<form action="/campgrounds/<%=campground._id%>?_method=PUT" enctype="multipart/form-data" method="POST">
<div class="form-group">
<input class="form-control" type="text" name="name" value="<%= campground.name%>">
</div>
<div class="form-group">
<input class="form-control" type="number" name="price" value="<%= campground.price%> min="0.01" step="0.01"">
</div>
<div class="form-group">
<input class="form-control" type="file" name="image" value="\<%= campground.image%>">
</div>
<div class="form-group">
<input class="form-control" type="text" name="description" value="<%= campground.description %>">
</div>
<div class="form-group">
<button class="btn btn-primary btn-large btn-block">Submit</button>
</div>
</form>
Go back
</div>
</div>
<%-include ('../partials/footer') %>

Related

How to upload images on node js?

I am having issues getting any image data on the form in the ejs file after submitting. Upon debugging, there is a req.body.image which has the filename but req.file is undefined. I have tried many sites online detailing how to upload images but none seem to be working, any suggestions?
Part of the code in server.js file:
require("dotenv").config()
const express = require("express");
const cors = require("cors");
const path = require('path')
const app = express();
const mongoose = require("mongoose")
const fs = require('fs')
const multer = require('multer')
const fileupload = require("express-fileupload");
const Grid = require("gridfs-stream");
let gfs;
app.use(fileupload());
require('./routes/auth.routes')(app);
require('./routes/user.routes')(app);
app.use('/uploads', express.static('uploads'))
app.set('view engine', 'ejs');
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(express.static(path.join(__dirname, 'static')));
app.use(cors(corsOptions));
app.use(express.json());
var storage = multer.diskStorage({
destination: function(req,file,cb){
cb(null, '../uploads/')
},
filename: function(req, file, cb) {
cb(null, Date.now()+file.originalname)
}
})
const fileFilter = (req,res,cb) =>{
if(file.mimetype === "image/jpeg"||file.mimetype ==='image/png'){
cb(null, true);
}else{
cb(null,false);
}
}
var upload = multer({
storage:storage,
fileFilter: fileFilter
})
app.post('/makepost', upload.single('image'), async function(req, res, next){
if(req.file)
{
const pathName=req.file.path;
res.send(req.file.filename)
}
await db.post.create({
"author": "",
"title": req.body.title,
"img": req.file,
"description": req.body.description
})
res.render('pages/index', {loggedin: loggedin, test: test});
});
createpost.ejs page:
<!DOCTYPE html>
<html lang="en">
<head>
<%- include('../partials/head'); %>
</head>
<body class="u-body u-xl-mode"><div class="u-clearfix u-sheet u-valign-middle u-sheet-1">
<%- include('../partials/navbar', {loggedin:loggedin}); %>
<section>
<h1 align="center">Create post</h1>
</section>
<div class="createpost">
<form action="/makepost" method="post">
<label for="title">
<!-- font awesome icon -->
<i class="fab fa-adversal"></i>
</label>
<input type="text" name="title" placeholder="Title" id="title" required>
<br>
<label for="description">
<i class="fa fa-paper-plane"></i>
</label>
<input type="text" name="description" placeholder="Description" id="description" required>
<br>
<label for="image">Upload Image</label>
<input type="file" id="image" name="image" required>
<input type="submit" value="Upload post">
</form>
</div>
</div>
<footer>
<%- include('../partials/footer'); %>
</footer>
</body>
</html>
Add enctype='multipart/form-data' attr to the form.
Whenever you have files inside a form it is required that you have this.
example:
<form action="/makepost" method="post" enctype="multipart/form-data">
...
</form>

NodeJS/ExpressJS doesn't redirect to the homepage

I am working on a shopping cart application in nodejs/expressjs. I am having some problems with redirecting back to the '/' page after submitting the credentials of the user at the sign up. I didn't find any articles related to this problem. I am also using CSURF protection.
The problem is if I press the submit button, from
localhost:3000/user/signup/
goes to
localhost:3000/user/signup?email=something&password=somepassword&_csrf=QQdMG3kT-kOPAucSUipAlAUQaRSoLJrWlMQc
And it doesn't go back to the homepage. (localhost:3000)
This is the code from the index.js file:
var express = require('express');
var router = express.Router();
var Product = require('../models/product');
var csrf = require('csurf');
var csrfProtection = csrf();
/* GET home page. */
router.use(csrfProtection);
router.get('/', function(req, res, next) {
res.setHeader("Content-Type", "text/html");
Product.find(function(err, docs){
var productChunks = [];
chunkSize = 2;
for(var i = 0; i < docs.length; i+= chunkSize){
productChunks.push(docs.slice(i, i + chunkSize));
}
res.render('shop/index', { title: 'Humble', products: docs });
});
});
router.get('/user/signup', function(req, res, next){
res.render('user/signup', {csrfToken: req.csrfToken()});
});
router.post('/user/signup', function(req, res, next){
res.redirect('/');
});
module.exports = router;
This is the code from the signup.hbs file:
<h1 class = "subtitlu"><b>Sign UP!</b></h1>
Validation Errors
<form action = "/user/signup" metod = "post"
style =
"box-shadow: 5px 10px 18px #888888;
font-family:Helvetica-Medium;
font-size:25px;
padding:25px;
margin-bottom:30px;
margin-top:30px;
overflow:hidden;">
<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">Parola</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" style="background-color:rgb(0, 219, 66); position: relative;
float: right;">Create an account!</button>
</form>
you have a typo in your form: metod = "post" updating metod to method should do the job
redirecting is not working because there's no POST request to /user/signup

Error During File upload in Express.js using Multer

I am learning Node.js from a book "Web Development with Nodejs and MongoDB" and is Stuck at a point where I have to upload a Image using Multer.
The Code goes like this :-
Below is My Configure.js file :
var path = require('path'),
routes = require('./routes'),
exphbs = require('express-handlebars'),
express = require('express'),
bodyParser = require('body-parser'),
cookieParser = require('cookie-parser'),
morgan = require('morgan'),
methodOverride = require('method-override'),
errorHandler = require('errorhandler');
multer = require('multer');
moment = require('moment');
var upload = multer({ dest: './public/upload/temp' });
module.exports = function(app) {
app.use(morgan('dev'));
app.use(methodOverride());
app.use(cookieParser('some-secret-value-here'));
routes(app);
app.post('/public/upload/temp', upload.single('img'), function(req, res) {
//var form_description = req.body.description;
console.log(req.file.name);
// insert operations into database get placed here
res.redirect('/');
});
app.use('/public/', express.static(path.join(__dirname,
'../public')));
if ('development' === app.get('env')) {
app.use(errorHandler());
}
app.engine('handlebars', exphbs.create({
defaultLayout: 'main',
layoutsDir: app.get('views') + '/layouts',
partialsDir: app.get('views') + '/partials',
helpers: {
timeago: function(timestamp) {
return moment(timestamp).startOf('minute').fromNow();
}
}
}).engine);
return app;
};
Below is the Handlebar file or (HTML) file :-
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title">
Upload an Image
</h3>
</div>
<form method="post" action="/images" enctype="multipart/formdata">
<div class="panel-body form-horizontal">
<div class="form-group col-md-12">
<label class="col-sm-2 control-label" for="file">Browse:</label>
<div class="col-md-10">
<input class="form-control" type="file" name="file" id="file">
</div>
</div>
<div class="form-group col-md-12">
<label class="col-md-2 control-label" for="title">Title:</label>
<div class="col-md-10">
<input class="form-control" type="text" name="title">
</div>
</div>
<div class="form-group col-md-12">
<label class="col-md-2 control-label" for="description">Description
</label>
<div class="col-md-10">
<textarea class="form-control" name="description" rows="2"></textarea>
</div>
</div>
<div class="form-group col-md-12">
<div class="col-md-12 text-right">
<button type="submit" id="login-btn"
class="btn btn-success" type="button">
<i class="fa fa-cloud-upload ">
</i> Upload Image</button>
</div>
</div>
</div>
</form>
</div>
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">
</h3>
</div>
<div class="panel-body">
{{#each images}}
<div class="col-md-4 text-center" style="padding-bottom:1em;">
<a href="/images/{{ uniqueId }}">
<img src="/public/upload/{{filename}}" alt="{{title}}" style="width:
175px; height: 175px;" class="imgthumbnail">
</a></div>
{{/each}}
</div>
</div>
Below is the image.js Controller File :-
var fs = require('fs');
var path = require('path');
module.exports = {
index: function(req, res) {
var viewModel = {
image: {
uniqueId: 1,
title: 'Sample Image 1',
description: 'This is a sample.',
filename: 'sample1.jpg',
views: 0,
likes: 0,
timestamp: Date.now
},
comments: [{
image_id: 1,
email: 'test#testing.com',
name: 'Test Tester',
gravatar: 'http://lorempixel.com/75/75/animals/1',
comment: 'This is a test comment...',
timestamp: Date.now
}, {
image_id: 1,
email: 'test#testing.com',
name: 'Test Tester',
gravatar: 'http://lorempixel.com/75/75/animals/2',
comment: 'Another followup comment!',
timestamp: Date.now
}]
};
res.render('image.handlebars', viewModel);
},
create: function(req, res) {
var possible = 'abcdefghijklmnopqrstuvwxyz0123456789',
imgUrl = '';
for (var i = 0; i < 6; i += 1) {
imgUrl += possible.charAt(Math.floor(Math.random() *
possible.length));
}
var tempPath = req.file.path,
ext = path.extname(req.file.name).toLowerCase(),
targetPath = path.resolve('./public/upload/' + imgUrl + ext);
if (ext === '.png' || ext === '.jpg' || ext === '.jpeg' || ext ===
'.gif') {
fs.rename(tempPath, targetPath, function(err) {
if (err) throw err;
res.redirect('/images/' + imgUrl);
});
} else {
fs.unlink(tempPath, function() {
if (err) throw err;
res.json(500, { error: 'Only image files are allowed.' });
});
}
},
like: function(req, res) {
res.send('The image:like POST controller');
},
comment: function(req, res) {
res.send('The image:comment POST controller');
}
};
When run the server and visit the website on localhost and try to upload a image by clicking on Upload Image button this error comes :-
Cannot read property 'path' of undefined
at create (G:\Docs\Node.js\Project\imgploader.io\controllers\image.js:40:32)
at Layer.handle [as handle_request] (G:\Docs\Node.js\Project\imgploader.io\node_modules\express\lib\router\layer.js:95:5)
at next (G:\Docs\Node.js\Project\imgploader.io\node_modules\express\lib\router\route.js:137:13)
at Route.dispatch (G:\Docs\Node.js\Project\imgploader.io\node_modules\express\lib\router\route.js:112:3)
at Layer.handle [as handle_request] (G:\Docs\Node.js\Project\imgploader.io\node_modules\express\lib\router\layer.js:95:5)
at G:\Docs\Node.js\Project\imgploader.io\node_modules\express\lib\router\index.js:281:22
at Function.process_params (G:\Docs\Node.js\Project\imgploader.io\node_modules\express\lib\router\index.js:335:12)
at next (G:\Docs\Node.js\Project\imgploader.io\node_modules\express\lib\router\index.js:275:10)
at Function.handle (G:\Docs\Node.js\Project\imgploader.io\node_modules\express\lib\router\index.js:174:3)
at router (G:\Docs\Node.js\Project\imgploader.io\node_modules\express\lib\router\index.js:47:12)
What is the Problem ? I have tried everything available on the Internet but still the same !
Please Help
Maybe because you have used ( ; ) at the end of error handler declaration
errorHandler = require('errorhandler');
also in your HTML name attribute should be img as you have used it multer.

i am not able to fetch data from html controls using get method in nodejs and mongodb

problem in code
var userID = req.userid;
var pwd = req.pwd;
console.log("userid = " + userID + "pass = " + pwd);
the console shows values undefined instead of input data
the console shows values undefined instead of input data
I want to take data from an html file and insert into the mongo database using get method. But I am not able to fetch data from the textbox.
Code in nodejs(index.js)
const express = require('express');
const path = require('path');
const bodyparser = require("body-parser");
const mongoose = require('mongoose');
const app = express();
app.use(bodyparser());
app.use(bodyparser.urlencoded({
extended: false
}));
app.use(bodyparser.json());
app.set('port', (process.env.PORT || 1000));
mongoose.connect('mongodb://localhost/TrackDB');
var Schema = new mongoose.Schema({
username: String
, pass: String
});
var users = mongoose.model('users', Schema);
app.get("/register", function (req, res) {
var userID = req.userid;
var pwd = req.pwd;
console.log("userid = " + userID + "pass = " + pwd);
new users({
username: userID
, pass: pwd
}).save(function (err, doc) {
if (err) {
res.json(err);
}
else res.send("Successfully Registerd!");
});
console.log("users = " + users);
});
app.get("/", (req, res) => {
res.sendFile(path.join(__dirname, './public/index.html'));
});
app.listen(1000, () => {
console.log("Server Start......");
});
HTML Page (index.html)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>LOGIN/REGISTER</title>
<style>
#container {
width: 40%;
margin: auto;
border: 1px solid;
padding: 10px;
padding-left: 200px;
border-radius: 10px;
}
</style>
</head>
<body>
<div id="container">
<h1>Register</h1>
<form action="/register">
<div id="register">
<input type="text" name="userid" id="txt_userid" placeholder="Enter user id">
<br>
<input type="password" name="pwd" id="txt_pass" placeholder="Enter password">
<br>
<br>
<button type="submit" id="btn_register">Register</button>
</div>
</form>
<h1>Login</h1>
<form action="/login">
<br>
<br>
<div id="login">
<input type="text" name="user" id="userid" placeholder="Enter user id">
<br>
<br>
<input type="password" name="passw" id="pass" placeholder="Enter password">
<br>
<br>
<button type="submit" id="btn_login">Login</button>
</div>
</form>
<h1 id="msg"></h1> </div>
</body>
</html>
Try this code
var userID =req.query.userid;
var pwd = req.query.pwd
You need to use POST request, and the data won;t be available in req object. Instead it will be available in req.body
Try:
var userID = req.body.userid;
var pwd = req.body.pwd;
console.log("userid = " + userID + "pass = " + pwd);
You have to use app.post method in node.js.
And use method = post.
<form action="/register" method="post">
<div id="register">
<input type="text" name="userid" id="txt_userid" placeholder="Enter user id">
<br>
<input type="password" name="pwd" id="txt_pass" placeholder="Enter password">
<br>
<br>
<button type="submit" id="btn_register">Register</button>
</div>
</form>
Sending data to node uses post, delete, put methods. But if you wish to fetch data back from node you can use .get() method.
I suggest try to print req(i.e console.log(req)). As might be data is stored in req.body.

Why can't I successfully to fetch url from form and thus attribute it to the source(src) of images?

I've having an issue I shouldn't be having with my Node/Express code(s). I can't for the life of me get the image source (src) attribute to work, hence the images added from a form aren't being displayed. It just displays as unknown. I have no idea where I'm going wrong, and have gone through the whole code(s) multiple times, but nothing seems out of place.
The JS code is as follows:
var express = require("express"),
app = express(),
bodyParser = require("body-parser"),
mongoose = require("mongoose");
mongoose.connect("mongodb://localhost/yelpcamp");
app.use(bodyParser.urlencoded({extended: true}));
app.set("view engine", "ejs");
//Camp Schema
var campgroundSchema = new mongoose.Schema({
name: String,
image: String
});
var Campground = mongoose.model("Campground", campgroundSchema);
app.get("/", function(req, res) {
res.render("landing");
});
app.get("/campgrounds", function(req, res){
Campground.find({}, function(err, sites) {
if(err) {
console.log(err);
}
else {
res.render("campgrounds", {
campgrounds:sites
});
}
});
});
app.post("/campgrounds", function(req, res){
//Fetching data from form
var name = req.body.campName;
var url = req.body.imageUrl;
var newCamp = {
name: name,
image: url
};
//New Campground and Save to DB
Campground.create(newCamp, function(err, campground) {
if(err) {
console.log(err);
}
else {
//Redirect to Camp Page
console.log(campground);
res.redirect("/campgrounds");
}
});
});
app.get("/campgrounds/new", function(req, res){
res.render("new");
});
app.listen(4500, function(){
console.log("Yelp Camp Server Started!!!");
});
The following are the relevant EJS codes:
Form EJS
<div class="container">
<form action="/campgrounds" method="POST">
<label for="campName">Name</label>
<input type="text" id="campName" name="campName" placeholder="Add Campground Name">
<label for="campImage">Image</label>
<input type="url" id="campImage" name="imageUrl" placeholder="Add Image Url">
<input type="submit" name="submit" value="Add Campground">
</form>
Go Back
</div>
Add Image EJS
<div class="container">
<h1 style="margin-top: 8%;">Campgrounds Presentation</h1>
<div class="row">
<% campgrounds.forEach(function(campground) { %>
<div class="col-md-4 col-sm-6 col-xs-12">
<div class="thumbnail">
<img src="<%= campground.image %>">
<h3 class=text-center><%= campground.name %></h3>
</div>
</div>
<% }); %>
</div>
</div>

Categories

Resources