Req.file object is always undefined, HTTP file upload - node.js

I'm trying to upload a file in meteor using HTTP POST method and enctype="multipart/form-data"
WebApp.connectHandlers.use("/api/v1/upload", function(req, res, next) {
console.log(req.files); //undefined
console.log(req.file); //undefined
console.log(req);
})
I tried with WebApp but getting undefined file property under request object
I also tried with multer and Picker but no luck.
const _multerInstanceConfig = { dest: '/tmp' }; // Temp dir for multer
const _multerInstance = multer(_multerInstanceConfig);
Picker.middleware(_multerInstance.single('photo'));
Picker.route('/api/v1/upload', function(params, req, res, next) {
console.log(req.files); //undefined
console.log(req.file); //undefined
console.log(req);
})
This is simplest form I'm trying to upload is
<form action="http://localhost:3000/api/v1/upload" method="POST" enctype="multipart/form-data">
<input type="file" name="file" />
<input type="submit" value="Upload File" />
</form>
Am I missing something here? not sure.
Also, I don't want to upload files using base64 data string via DDP as it very slow.
I've check couple of link also with no luck
multer - req.file always undefined
https://github.com/noris666/Meteor-Files-POST-Example
PS: I need to upload images via native Android/iOS clients.

Thanks, everyone, who has spent their time on my question, I got the solution for the problem from git issue, I raised.
I'm posting here my solution if someone else also faces the similar problem.
It was because of the name of this input field
<input type="file" name="file" />
which doesn't match with
Picker.middleware(_multerInstance.single('photo'));
changing either of them to will make it work perfectly.

Related

what is use of router and model in loopback

hello guys i m new to loopback so can anyone help me with this basic. i had created a some code but don't know how this flow (from route to model)
here is route.js code for login
var path = require('path');
module.exports = function(app) {
app.get('/', function(req, res) {
res.render('login');
});
app.post('/login', function(req, res) {
//from here i should go to login model
});
};
here is my login.ejs
<form action="/login" method="post">
<input type="text" name="username" placeholder="username">
<input type="password" name="password" placeholder="password">
<input type="submit" name="" value="Submit">
</form>
now my question is that how i can use login model from route.js (url is like "login") i know i can use this type as describe below in route.js but i want that first it go to router and from then i go to login model more description eg it go through "/login" route from there it go to login model where i want to add insert login after that if it response success then it go to "/home" else it go to "/"
"var User = app.models.user;"
i what something like this in user.js (model)
module.exports = function(User) {
//here i want to accept login form method and insert it into dataabase
};
or this is not possible or it is incorrect way i don't know much so please help
what is different between if i use business login in router and model i m new so please help.
First go to the loopBack documentation and read it carefully how to create models and its control flow , surely you will get clear picture
https://loopback.io/doc/en/lb2/Project-layout-reference.html

(Self Q&A) HOW TO SETUP AND USE the MULTER MIDDLEWARE) for single file upload ( Expressjs/Nodejs )

Just wanted to post an answer to a beginner level question on HOW TO SETUP AND USE the MULTER MIDDLEWARE in Expressjs/Nodejs
Hope this saves your time
There should be two files:
1.Jade file(which shall contain the form lets assume index.jade)
2.JS file(which is located in the routes folder, and which directs to the index.jade file in the views folder)
SETUP index.jade file
//not a jade file so convert it to jade
//enctype is set to multipart/form-data --- multer requirement
<form method="post" role="form" enctype="multipart/form-data">
<div class="form-group">
<label for="upload">Email address:</label>
//name attribute to access in index.js route file
<input type="file" class="form-control" name="upload" id="upload">
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
//very important
(a)In the Jade file the form must contain the attribute of enctype = "multipart/form-data"
(b)Input should have a name attribute which gets accessed in the index.js file
SETUP JS ROUTE FILE(index.js) not in app.js
var express = require('express')
var multer = require('multer')
var upload = multer({ dest: 'uploads/' }) //set dest to where you want to upload the file
var app = express()
// SINGLE FILE UPLOAD
app.post('/', upload.single('upload'), function (req, res, next) {
//since we are performing a single file upload req.file will be used and not req.files
// req.file would attach the file with upload fieldname ~ upload is the name attribute given in the form
//now use req.file to access the file
//for example
console.log(req.file); // this would display the file attributes in the log
})

Send ejs field to a nodejs file

I have the following ejs code.
<form action="/" class = "form-horizontal" method="post">
<textarea class = 'form-control departureCode' name = "departureCode" rows= "1"></textarea>
</form>
This is my post handler code in routes.js file.
routes.post('/', (req, res, next) => {
let departureCode = JSON.parse(req.body.departureCode);
console.log(departureCode);
});
I m not getting this to work successfully. I am getting undefined token error inside my post handler. Could you please help me?
removed JSON.Parse from
let departureCode = JSON.parse(req.body.departureCode);
It worked. Also, made changes suggested by Yogesh Patel in the comments. Thank you all.

Formidable upload file don't trigger

Development and test environment:
Windows 8 64bit
node version installed 0.10.5
npm version 1.2.18
express framework
formidable module used for file uploading
Firefox and Internet Explorer browsers
HTML code:
<form id="caricaMasterImg" method="post" enctype="multipart/form-data" action="/image/upload">
<input type="file" id="masterImg" name="masterImg" value="Sfoglia" accept="image/*"/>
<input type="submit" value="carica" id="submitLoadImg" />
</form>
app.js code:
var image = require('./route/image');
app.post('/image/upload', image.upload);
routes/image.js code:
exports.upload = function(req, res){
var form = new formidable.IncomingForm();
form.uploadDir = path.join(__dirname, 'tmp');
console.log('Upload directory is: '+form.uploadDir);
fs.exists(form.uploadDir, function (exists) {
console.log('is an existing directory? '+exists);
});
form.parse(req, function(err, fields, files) {
console.log(fields);
console.log(files);
});
};
The issue:
When submit button is clicked I expect to see the file logged with console.log(files) instruction. Log writes:
Upload directory is: C:\Liber-I\app\FileSystemManager\routes\tmp
is an existing directory? true
No more log is written on application console for several minutes.
I test the case of no-file submission and it seems it is acting the same! It is a too weired behaviour to be a nodejs problem, where am I doing wrong?
I think I did nothing wrong. Truth is I am not able to fix this problem, so I decided for a good work around. I choose to use connect-multiparty for file uploading and it is working just great.

Accessing Upload Image in Server Side

I am supposed to upload image & store it in GridFS. My problem here is I am not getting selected image by user on server side.
<input type="file" name="letterhead" />
Server Side
console.log(req.files);
It shows me undefined.
I see you tagged it as AngularJS so I assume you use the file input inside AngularJS controller. As far as I'm aware ngModel doesn't work on file inputs. I personally do it this way
<input type="file" id="uploadImage" name="uploadImage" onchange="angular.element(this).scope().setFiles(this)">
and then in controller
$scope.setFiles = function (element) {
$scope.$apply(function () {
$scope.file = element.files[0];
//from now on you can do whatever you want with your image $scope.file
});
};

Resources