I'm trying to upload a photo using Node.js. But when I upload, it shows this error:
Cannnot read property file of undefined
at C:\new\file.js:13:26
Looks like I'm doing something wrong with req.files.file.name which I don't understand. What can be the issue?
Here's the code:
file.js
var express = require('express');
var app = express();
var fs = require('fs');
var bodyParser = require('body-parser');
var multer = require('multer');
app.use(express.static('public'));
app.use(bodyParser.urlencoded({extended: false}));
app.use(multer({dest: '/files/'}).single('file'));
app.get('/index.html', function (req, res) {
res.sendFile(__dirname + '/' + '/index.html')
});
app.post('/file_upload', function (req, res) {
console.log(req.files.file.name);
console.log(req.files.file.path);
console.log(req.files.file.type);
var file = __dirname + '/' + req.files.file.name;
fs.readFile(req.files.file.name, function (err, data) {
fs.writeFile(file, data, function (err) {
if (err) {
console.log("Error reading");
} else {
response = {
message: 'file uploaded successfully',
filename: req.files.file.name
};
}
console.log(response);
res.end(JSON.stringify(response));
});
});
});
var server = app.listen(8081, function () {
var host = server.address().address
var port = server.address().port
console.log("The server is running at http://%s:%s ", host, port);
});
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="http://127.0.0.1:8081/file_upload" method="POST" enctype="multipart/form-data">
<input type="file" name="file">
<input type="submit" value="submit">
</form>
</form>
</body>
</html>
Here's what I do, which works fine:
var uploadPath = 'public/uploads/';
var upload = multer({dest: uploadPath});
router.post('/image', upload.single('thePhoto'), function (req, res) {
var uploadedFile = uploadPath + req.file.filename;
The problem can be caused because you have already added multer in app.use() which parses all the data before the control goes to post method. So I think you should either use fs or multer but not both.
Related
I am able to store image path in mongodb.Here I am storing image paths in array format. Using document Id I need to add another image i.e., I want to push another image path into that array.So my question is how can I store another image path in mongodb.
Here I am uploading image using html file. This is my code index.html
<form id="uploadForm"
enctype="multipart/form-data"
action="/api/file"
method="post"
>
<input type="file" name="userFile"/>
<input type="submit" value="Upload File" name="submit">
</form>
Here is my server code server.js
var express=require('express');
var multer=require('multer');
var bodyParser = require('body-parser');
var Image=require('./models/image');
var Product=require('./models/product');
var mongoose=require('mongoose');
var path = require('path');
var rand;
var urlencodedParser = bodyParser.urlencoded({ extended: false });
var config = require('./config');
mongoose.connect(config.mongoUrl);
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function () {
console.log("Connected correctly to server");
});
var app=express();
var ejs = require('ejs')
app.set('view engine', 'ejs')
var storage = multer.diskStorage({
destination: function(req, file, callback) {
callback(null, './public/uploads')
},
filename: function(req, file, callback) {
//callback(null, file.fieldname + '-' + Date.now() + path.extname(file.originalname))
//callback(null, file.originalname)
rand=Date.now() + path.extname(file.originalname);
callback(null, file.fieldname + '-' + rand);
}
})
var upload = multer({
storage: storage});
app.get('/api/file',function(req,res){
res.sendFile('E:/saas/nodejs/uploads/db/views/index.html');
});
app.post('/api/file',upload.single('userFile'), function(req, res) {
console.log(req.file);
console.log(req.file.path);
Image.create({imagePaths:[{imagepath:req.file.path}]},function(err,img){
if (err) throw err;
console.log(img);
console.log('Path created!');
var id = img._id;
res.writeHead(200, {
'Content-Type': 'text/plain'
});
res.end('Added the image path with id: ' + id);
});
})
var route=require('./routes/route');
app.use('/route',route);
app.listen(3000,function(){
console.log("Server listening on 3000");
});
After running the server I will use this in browser http://localhost:3000/api/file using this I am able to upload file and I will get mongodb document id in response.Using this Id how can I upload another image path.
Use $push to store path in array
schemaName.findByIdAndUpdate(
{ req.headers.id },
{ $push: { imagePath: '/newPath' } },
(err,response)=>{
if(err){
console.log(err);
}
});
My Code:
Js File:
var formidable = require('formidable');
var fs = require('fs');
var ex = require('express');
var fse = require('fs-extra');
var app = ex();
app.set('view engine', 'ejs');
app.get('/form', function(req, res) {
res.render(__dirname + '/views/front.ejs', {title: 'form-page'});
}).listen(8081);
app.post('/form', function(req, res) {
var form = new formidable.IncomingForm();
form.parse(req, function (err, fields, files) {
var oldpath = files.fil.path;
var newpath = __dirname + '/uploads/' + files.fil.name;
var fileExt = files.fil.name.split('.').pop();
fse.move (oldpath, newpath, function (err) {
if (err) { throw err; }
});
});
});
Html/Ejs File:
<html>
<title> <%= title %> </title>
<body>
<h2> Form </h2>
<form action="/form" method="post" enctype="multipart/form-data">
Name: <input type="text" name="name" /><br>
File: <input type="file" name="fil" />
<input type="submit" value="Submit">
</form>
</body>
</html>
all the packages are properly installed and with this code, files(with any extension) are getting uploaded to the desired directory properly.
What i want is for only image files to be uploaded ex:- jpeg,png etc
Thank you.
Use this code:
form.onPart = function (part) {
if(!part.filename || part.filename.match(/\.(jpg|jpeg|png)$/i)) {
this.handlePart(part);
}
else {
console.log(part.filename + ' is not allowed');
}
}
Source: uploading files using express.js and node, limiting extensions
Im testing examples of Express but i have problems with this one.
I'm trying to execute this code example (example taken from the web) and i having this error when i try to upload an image.
TypeError: Cannot read property 'file' of undefined
SERVER
var express = require('express');
var app = express();
var fs = require("fs");
var bodyParser = require('body-parser');
var multer = require('multer');
app.use(express.static('public'));
app.use(bodyParser.urlencoded({ extended: false }));
var multer = require('multer');
app.get('/index.html', function (req, res) {
res.sendFile( __dirname + "/" + "index.html" );
})
app.post('/file_upload', function (req, res) {
console.log(req.files.file.name);
console.log(req.files.file.path);
console.log(req.files.file.type);
var file = __dirname + "/" + req.files.file.name;
fs.readFile( req.files.file.path, function (err, data) {
fs.writeFile(file, data, function (err) {
if( err ){
console.log( err );
}else{
response = {
message:'File uploaded successfully',
filename:req.files.file.name
};
}
console.log( response );
res.end( JSON.stringify( response ) );
});
});
})
var server = app.listen(8081, function () {
var host = server.address().address
var port = server.address().port
console.log("Example app listening at http://%s:%s", host, port)
})
CLIENT
<html>
<head>
<title>File Uploading Form</title>
</head>
<body>
<h3>File Upload:</h3>
Select a file to upload: <br />
<form action = "http://127.0.0.1:8081/file_upload" method = "POST"
enctype = "multipart/form-data">
<input type="file" name="file" size="50" />
<br />
<input type = "submit" value = "Upload File" />
</form>
</body>
</html>
Try this...
<html>
<head>
<title>File Upload</title>
</head>
<body>
<h3>File Upload:</h3>
Select a file to upload: <br />
<form action = "http://127.0.0.1:8081/file_upload" method = "POST"
enctype = "multipart/form-data">
<input type="file" name="foo" size="50" />
<br />
<input type = "submit" value = "Upload File" />
</form>
</body>
</html>
Server.js
var express = require('express');
var app = express();
var path = require("path");
var bodyParser = require('body-parser');
var multer = require('multer');
app.use(express.static('public'));
app.use(bodyParser.urlencoded({ extended: false }));
app.get('/index.html', function (req, res) {
res.sendFile( __dirname + "/" + "index.html" );
})
var upload = multer({
dest: path.join(__dirname, '../public/upload/temp')
});
app.post('/file_upload', upload.single('foo'), function(req, res) {
if (req.file) {
console.dir(req.file);
return res.end('Uploaded successfuly');
}
res.end('No file found');
});
var server = app.listen(8081, function () {
var host = server.address().address
var port = server.address().port
console.log("Example app listening at http://%s:%s", host, port)
})
For multi upload change upload.single('foo') to upload.array('foo')
I tried to file upload with NodeJS + ExpressJS + Multer but does not work well.
My ExpressJS Version is 4.12.3
this is my source
server.js:
var express = require('express'),
multer = require('multer');
var app = express();
app.use(express.static(__dirname + '/public'));
app.use(multer({ dest: './uploads/'}));
app.post('/', function(req, res){
console.log(req.body); // form fields
console.log(req.files); // form files
res.status(204).end()
});
app.get('/', function(req, res) {
res.sendFile('public/index.html');
});
app.listen(5000, function() {
console.log("start 5000");
});
public/index.html:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body>
<form method="post" enctype="multipart/form-data">
<input id="file" type="file"/>
<button type="submit">test</button>
</form>
</body>
</html>
My NodeJS Console Log when I click Submit Button:
"C:\Program Files\nodejs\node.exe" server.js
start 5000
{}
on NodeJS Console, there is empty object at req.files
Is some problem on my source?
I don't see you calling any API to upload file on click of submit button. Let me give you more comprehensive implementation.
multer config in app.js
app.use(multer({
dest: './uploads/',
rename: function (fieldname, filename) {
return filename.replace(/\W+/g, '-').toLowerCase() + Date.now()
},
onFileUploadStart: function (file) {
console.log(file.fieldname + ' is starting ...')
},
onFileUploadData: function (file, data) {
console.log(data.length + ' of ' + file.fieldname + ' arrived')
},
onFileUploadComplete: function (file) {
console.log(file.fieldname + ' uploaded to ' + file.path)
}
}));
View
<form id="uploadProfilePicForm" enctype="multipart/form-data" action="/user/profile_pic_upload" method="post">
<input type="file" multiple="multiple" id="userPhotoInput" name="userPhoto" accept="image/*" />
<input type="submit" name="submit" value="Upload">
</form>
End point '/user/profile_pic_upload' POST calls uploadProfilePic in controller
var control = require('../controllers/controller');
app.post('/user/profile_pic_upload',control.uploadProfilePic);
Upload profile pic logic in users controller
uploadProfilePic = function(req,res){
// get the temporary location of the file
var tmp_path = req.files.userPhoto.path;
// set where the file should actually exists
var target_path = '/Users/narendra/Documents/Workspaces/NodeExpressWorkspace/MongoExpressUploads/profile_pic/' + req.files.userPhoto.name;
// move the file from the temporary location to the intended location
fs.rename(tmp_path, target_path, function(err) {
if (err) throw err;
// delete the temporary file, so that the explicitly set temporary upload dir does not get filled with unwanted files
fs.unlink(tmp_path, function() {
if (err) {
throw err;
}else{
var profile_pic = req.files.userPhoto.name;
//use profile_pic to do other stuffs like update DB or write rendering logic here.
};
});
});
};
Try this
var multer = require('multer')
var storage = multer.diskStorage({
destination: function (request, file, callback) {
callback(null, './uploads/');
},
filename: function (request, file, callback) {
console.log(file);
callback(null, file.originalname)
}
});
var upload = multer({ storage: storage });
app.post('/', upload.single('photo'), function (req, res) {
console.log(req.body) // form fields
console.log(req.file) // form files
res.status(204).end()
});
ref:
http://wiki.workassis.com/nodejs-express-get-post-multipart-request-handling-example/
I am new to node.js and I m trying to play around with GraphicsMagic. I have installed GraphicsMagic in my windows pc and also installed gm module with npm install. I am able to get fullsize image but not able to create thumbs with the following code. can anyone help me to go in correct direction?
var express = require('express');
var app = express();
var fs = require('fs');
var gm = require('gm');
app.configure(function () {
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
});
app.listen(8080);
console.log("App listening on port 8080");
app.post('/upload', function (req, res) {
fs.readFile(req.files.image.path, function (err, data) {
var imageName = req.files.image.name;
if (!imageName) {
console.log("There was an error");
res.redirect("/");
res.end();
} else {
var newPath = __dirname + "/uploads/fullsize/" + imageName;
var thumbPath = __dirname + "/uploads/thumbs/" + imageName;
fs.writeFile(newPath, data, function (err) {
gm(newPath)
.resize(240, 240)
.noProfile()
.write(thumbPath, function (err) {
if (!err) console.log('done');
res.redirect("/uploads/thumbs/"+imageName);
});
});
}
});
});
app.get('/uploads/thumbs/:file', function (req, res) {
file = req.params.file;
var img = fs.readFileSync(__dirname + "/uploads/thumbs/" + file);
res.writeHead(200, {'Content-Type': 'image/jpg' });
res.end(img, 'binary');
});
app.get('*', function (req, res) {
res.sendfile('./views/index.html'); // load the single view file (angular will handle the page changes on the front-end)
});
index.html:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<form method="POST" action="/upload" enctype="multipart/form-data">
<input type="file" name="image" />
<input type="submit" name="submit" value="Submit"/>
</form>
</body>
</html>