Cannot read property 'displayImage' of undefined - node.js

I am developing a web app with node js. When trying to upload a picture and save in the file system of the app I get the error :
Cannot read property 'displayImage' of undefined
My code for the post of the image is the following:
router.post('/upload', function (req, res, next) {
fs.readFile( req.files.displayImage.path, function (err, data) {
var newPath = __dirname + "/uploads/uploadedFileName";
fs.rename(newPath, 'filename', function (err) {
res.redirect('/');
});
});
});
And in the view
form(action="upload", method="post", enctype="multipart/form-data")
input(type="file", name="displayImage")
input(type='submit')
Thanks a lot for your help!
PS: I also have read some tutorials in where formidable module is used. It is recommended to use it or as I have done is enough?

Which version of express are you using ? In express 4.0 for multipart bodies you should use an alternatives.
For example, you can implement upload files using multer npm module
var multer = require('multer');
app.use(multer({dest: './uploads/'}));
//app.post('/upload', function (req, res, next) {
// console.log(req.files);
//});

Related

How to handle binary post data in Express?

I am wanting to post an image in the form of binary to my Express app.
I'm assuming it should come through in the req.body object but will need some form of middleware to be able to handle binary data?
When I send an image as binary from postman and try log req.body, the object is empty.
I am using express-generator as a boilder plate which comes with body-parser like so:
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
I had a look at Multer but think that is just for multipart data
Also looked at busboy but couldn't figure out if that will handle binary data.
Am I correct that the post data will still come through in req.body?
And what middleware do I need to handle binary data?
Thanks
The method I ended up using:
const multer = require('multer')
const storage = multer.memoryStorage()
const upload = multer({ storage: storage })
router.post('/upload', upload.single('image'), function(req, res, next) {
const image = req.file.buffer
});
Unfortunately, you can't use the body-parser to handle the binary data like files and stuff like that. But wut you can do is use a module call formidable to handle this
Example snipper
app.post('/', (req, res) => {
const form = new formidable.IncomingForm();
form.parse(req, (error, fields, files) => {
if(error){
console.log(error)
}
console.log(fields.name)
const cuteCat = files.cat_image;
console.log(cuteCat.name) // The origin file name
console.log(cuteCat.path) // The temporary file name something like /tmp/<random string>
})
});
<input name="cat_image" type="file" />
<input name="name" type="text" />

Node / Express - Is there a way to access static files from a controller method?

Inside the controller method, is there a way to access static files? I am using mailgun to send emails and need to send an html file in my request that is located in /public.
app.post('/', function(req, res) {
var html = getHtml(); // Need to get the html here to pass to mailgun
}
Is there a way to access the static file dir using some handy device provided by Express? No, not that I'm aware of.
Is there a way to get what you're trying to do done? Sure. Read it with the fs module. I like to use the path module, too, to generate my path to the file.
const path = require("path");
const fs = require("fs");
// Do however you like to build paths.
// I like to use resolve so I always get an absolute path.
const publicPath = path.resolve(__dirname, "public");
const htmlPath = path.join(publicPath, "thefile.html");
app.post('/', function (req, res, next) {
fs.readFile(htmlPath, "utf8", onFile);
function onFile (err, html) {
if (err) return next(err); // assuming you're using an error handler, like you probably should be
mailgunThatStuff(html, mgDone);
}
function mgDone (err) {
if (err) return next(err);
res.end("OK mailgun'd that thing");
}
}
That's a little wordy, maybe. Make sense?
you can try this
(app.js) you just mention static folder in app.js
var express = require('express');
var app = express();
app.use(express.static('public'));
index.html page in local flower in ./public/pages/
app.all('/', function (req, res) {
res.sendFile('index.html', {root: './public/pages/'});
});
try this its working fine

How do I get the body of a request from npm's multer if I don't upload a file?

I have a Node server using express.
I was originally using body-parser, but that doesn't allow for file uploads. So, I switched to multer (the easiest integration with express). However, in order to get any of the req (specifically req.body), this is my code:
var multer = require('multer');
var upload = multer({ dest : 'uploads/' });
server.all('/example', function (req, res, next) {
var up = upload.single('photo')
up(req, res, function(err) {
console.log(req.body); // I can finally access req.body
});
}
The problem with this, is that not all of my routes need to upload a file. Do I need to waste the CPU on calling upload.single() for each route in order to get access to the body? upload.single('') ends up not uploading any file, but it's still precious time spent on the main thread.
It appears that upload.single() waits for the callback, so it may not be as big of a deal as I'm making it, but I don't like calling functions when I don't have to.
Is there a way around calling upload.single(), or am I just making a bigger deal out of this than it really is?
For text-only multipart forms, you could use any of the multer methods, which are .single(), .array(), fields()
For instance using .array()
var multer = require('multer');
var upload = multer({ dest : 'uploads/' });
server.all('/example', upload.array(), function (req, res, next) {
console.log(req.body);
});
It doesn't really matter which you use, as long as it's invoked without arguments Multer will only parse the text-fields of the form for you, no files

receiving file in node-express uploaded with xhr

I have a xmlhttprequest which uploads the file and I am trying to receive it in my node-express server. but for some reason I am not able to retrieve the file content in the server. Not sure where I am missing it.
app.post('/api/uploadfiles', function(req, res) {
console.log("apicalled");
console.log(req);
console.log(req.body);
console.log(req.files);
console.log(JSON.stringify(req.files));
});
In order for you to see the files, you will need to add another middleware that parses multi-part request.
Try using connect-multiparty module like so:
var multipart = require('connect-multiparty'); //for files upload
var multipartMiddleware = multipart();//for files upload
app.post('/api/uploadfiles', multipartMiddleware, function(req, res) {
console.log("apicalled");
console.log(req);
console.log(req.body);
console.log(req.files);
console.log(JSON.stringify(req.files));
});

Express and uploading files

I am trying to upload files using express and formidable (eventualy forwarding to MongoDB and GridFS). I am starting by creating a form with a field of type file. On the action of that field I use the following route....
exports.addItem = function(req, res, next){
var form = new formidable.IncomingForm(),
files = [],
fields = [];
form
.on('file', function(field, file) {
console.log(field, file);
})
.on('end', function() {
console.log('-> upload done');
});
}
Everything runs fine but when I post I don't see anything in the console and it hangs.
The route looks like the following...
app.post('/item/add', routes.addItem, routes.getPlaylist, routes.index)
Any ideas?
UPDATE
Here is an example of grabbing the file, however, this still doesn't include formidable...
https://gist.github.com/2963261
The reason it is hanging is because you need to call next() to tell Express to continue.
Also use the bodyParser() middleware in express (included by default) to get the files. Something like this:
exports.addItem = function(req, res, next){
if(req.files.length > 0)
{
// process upload
console.log(req.files);
}
next();
}

Resources