NodeJS module mutler: "Error: Unexpected field" again - node.js

I am trying to use mutler in a simple exercise of learning nodejs. After I upload the file, get the "Unexpected filed" error. I tried everything it was written on this subject but I still cannot get rid of this error.
Here is my node.js code:
var express = require('express');
var app = express();
var fs = require("fs");
var bodyParser = require('body-parser');
var multer = require('multer');
var upload = multer({dest: 'tmp/'});
var type = upload.single('avatar');
app.use(express.static('public'));
app.use(bodyParser.urlencoded({ extended: false }));
app.get('/', function (req, res) {
res.sendFile( __dirname + "/" + "upload.html" );
})
app.post('/file_upload', type, async (req, res) => {
console.log(req.file);
})
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)
})
The html file used for upload:
<html>
<head>
<title>File Uploading Form</title>
</head>
<body>
<h3>Upload Profile:</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>
And the error I get in the web browser after upload:
Error: Unexpected field
at makeError (/home/mihai/nodejs/tutorial/node_modules/multer/lib/make-error.js:12:13)
at wrappedFileFilter (/home/mihai/nodejs/tutorial/node_modules/multer/index.js:40:19)
at Busboy.<anonymous> (/home/mihai/nodejs/tutorial/node_modules/multer/lib/make-middleware.js:114:7)
at emitMany (events.js:146:13)
at Busboy.emit (events.js:223:7)
at Busboy.emit (/home/mihai/nodejs/tutorial/node_modules/busboy/lib/main.js:38:33)
at PartStream.<anonymous> (/home/mihai/nodejs/tutorial/node_modules/busboy/lib/types/multipart.js:213:13)
at emitOne (events.js:115:13)
at PartStream.emit (events.js:210:7)
at HeaderParser.<anonymous> (/home/mihai/nodejs/tutorial/node_modules/dicer/lib/Dicer.js:51:16)
Can anybody tell me how to make it work? I have tried also on a Windows 7, with node v8.8.1 and get the same error.

The error indicates that multer encountered a file field in the request that it wasn't expecting.
You've told multer to expect a single field called avatar:
var type = upload.single('avatar');
Your file field is actually called file:
<input type="file" name="file" size="50" />
Change it to avatar and everything should work fine:
<input type="file" name="avatar" size="50" />

Related

Uploading a file with express-fileupload doesn't work

I'm attempting to upload a file with express-fileupload (express-fileupload) in Node js.
But I wasn't successfully yet.
My app.js (where my express server is running) looks like this:
const express = require('express');
const exphbs = require('express-handlebars');
const fileUpload = require('express-fileupload');
const app = express();
const port = 5000;
app.use(fileUpload({
debug: true
}));
app.use(express.static('./upload'));
const routes = require('./server/routes/task');
app.use('/', routes);
app.listen(port, () => console.log(`Listening on port ${port}`));
My task.js (where my routes are) looks like this:
const express = require('express');
const router = express.Router();
const taskController = require('../controllers/taskController');
router.post('/admin/fileUpload', taskController.fileUpload);
module.exports = router;
My taskController.js (where my routes are getting controlled) looks like this:
exports.fileUpload = (req, res) => {
let sampleFile;
let uploadPath;
if (!req.files || Object.keys(req.files).length === 0) {
res.render('admin', { error: `No files were uploaded!` });
} else {
sampleFile = req.files.sampleFile;
uploadPath = __dirname + '/upload/' + sampleFile.name;
sampleFile.mv(uploadPath, function (err) {
if (err) throw err;
res.render('admin', { alert: `File ${sampleFile.name} successfully uploaded!` });
}
}
}
My admin.hbs (I'm also using express-handlebars) looks like this:
<form method="POST" action="/admin/fileUpload">
<h2>Upload File</h2>
<input type="file" enctype="multipart/form-data" name="sampleFile">
<button type="submit">
</form>
So, my log looks like this when I start the express server:
[nodemon] starting `node app.js`
Listening on port 5000
Express-file-upload: Request is not eligible for file upload!
I'm trying to find the issue for hours but haven't had any luck yet.
So, it took me a while but I found my issue.
I've made a two little mistakes in my form and in my upload path.
<form method="POST" action="/admin/fileUpload">
<h2>Upload File</h2>
<input type="file" enctype="multipart/form-data" name="sampleFile">
<button type="submit">
</form>
Thats wrong. I've added the "enctype" in the wrong place. It should be in the form and not in the input field.
Solution for my form:
<form method="POST" action="/admin/fileUpload" enctype="multipart/form-data">
<h2>Upload File</h2>
<input type="file" name="sampleFile">
<button type="submit">
</form>
Solution for my upload path:
Instead of
uploadPath = __dirname + '/upload/' + sampleFile.name;
I need to do this
uploadPath = './upload/' + sampleFile.name;

Why passing JSON parameters from HTML to Node.js results in body parameter is undefined

I'm playing with Node.js for the first time trying to pass parameters from a form to my server and print them on the console
my html
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Hello Node</title>
</head>
<body>
<h1> we have a website</h1>
<form action="/contact" enctype="application/json" method="POST">
<input name="firstName" placeholder="firstName" type="text" size="30" />
<input name="lastName" placeholder="lastName" type="text" size="30" />
<input name="submit" type="submit" value="Send This">
</form>
</body>
</html>
i've tried both with and without enctype="application/json"
my app.js file
const express = require('express');
const app = express();
const bodyParser = require('body-parser')
var jsonParser = bodyParser.json()
app.listen(3333, () => {
console.log("Server is up and listening on 3003"); //print to the server console (the terminal!!)
})
app.post("/contact", jsonParser, function (req, res) {
console.log("in /contact");
console.log("request body:" + req.body);
console.log("request body first name:" + req.body.firstName);
console.log("request query first name:" + req.query.firstName);
})
I've tried with and without app.use(bodyParser.json({ type: 'application/*+json' }))
Output:
[object Object]
request body first name:undefined
request query first name:undefined
According to Mozilla documentation application/json content type is not allowed to be set as enctype value, so you can either send json using javascript or add support for application/x-www-form-urlencoded via app.use(bodyParser.urlencoded({ extended: false }))

How to handle POST request using express in Node.js? I have written following code which is not working

Not able to handle post request data using express in Node.js. I want to handle form data from index.html file in test.js file. Getting error:
POST /test" Error (404): "Not found"
Following is the code which I have written:
index.html
<html>
<body>
<form action="/test" method="POST">
Name: <input type="text" name="name"/>
<input type="submit" value="Submit"/>
</form>
</body>
</html>
test.js
var express = require("express");
var bodyParser = require('body-parser');
var app = express();
var urlEncodedParser = app.use(bodyParser.urlencoded({ // to support URL-encoded bodies
extended: false
}));
app.post('/test',urlEncodedParser, function(req,res){
console.log("Kushagra "+req.body);
});
app.listen(8080,function(){
console.log("Started in port 8080");
});
What to be done in order to receive form data from index.html file to test.js file.
// TODO: Place this code before route & put index.html to public directory
const path = require("path");
app.use(express.static(path.join(__dirname, "public")));

Formidable always returns empty fields and files when I upload a file in Node.js

Basically I want to upload a csv file from local computer and parse it in the backend to do required operations. I'm attaching the csv file in the front end. Checked that its not empty. But I'm unable to fetch the same in the server.
Is there something I'm missing or doing in the wrong way?
Here is what I have tried till now.
Front end code:
<form id="myForm" method="POST" enctype="multipart/form-data" action='/testcsv' >
<input type="file" id="file" />
<input type="submit" value="Submit">
</form>
Backend Code:
var express = require('express');
var methodOverride = require('method-override');
var http = require('follow-redirects').http;
var formidable = require('formidable');
var app = express();
const fs = require('fs');
app.use(methodOverride('_method'));
var bodyParser = require('body-parser');
app.use(bodyParser.json()); // support json encoded bodies
app.use(bodyParser.urlencoded({ extended: true })); // support encoded bodies
app.post('/testcsv', requireLogin, function(req, res) {
var form = new formidable.IncomingForm();
form.parse(req, function(err, fields, files) {
console.log(err);
console.log(fields);
console.log(files);
});
});
Log Output:
null
{}
{}
This problem is caused by Frontend code, it has nothing to do with Backend code (formidable).
For the following console.log statement:
console.log(err);
console.log(fields);
console.log(files);
err is null because there is no error.
fields is {} because in the form, all input fields are file selector. fields in formidable only indicate plain input field, such as <input type="text">.
files is {} because the name of file selector in the form is missing.
To get expected value, here is an example form:
<form id="myForm" method="POST" enctype="multipart/form-data" action='/testcsv' >
<input type="text" name="testtext" />
<input type="file" id="file" name="testfile" />
<input type="submit" value="Submit">
</form>
The console.log result for above form would be:
null
{ testtext: '....' }
{ testfile: File....}

nodejs throws cannot post error

I am trying to post the data from html form but it is showing an error "cannot POST".
This is my code:
controller/InquiryDetails.js:
var mongoose = require('mongoose'),
InquiryDetails = mongoose.model('InquiryDetails');
exports.add = function(req, res) {
InquiryDetails.create(req.body, function (error, details) {
if (error) return console.log(error);
return res.send(details);
});
}
routes/Inquiry.js
var express = require('express');
var router = express.Router();
var bodyParser = require('body-parser');
var app = express();
app.use(bodyParser.urlencoded({extended:true}));
app.post('/InquiryDetails', function(req,res,err){
if(err) console.log(err);
res.json(req.body);
console.log(req.body);
});
module.exports = router;
model/InquiryDetails.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var myskyll = new Schema({
name: String,
email: String,
state: String,
country: String,
school: String,
profession: String,
phone: Number
});
mongoose.model('InquiryDetails', myskyll);
app.js:
var express = require('express');
var mongoose = require('mongoose');
var request = require('request');
var connect = require('connect');
var serveStatic = require('serve-static');
connect().use(serveStatic(__dirname+"/index.html")).listen(8080);
var mongoUri = 'mongodb://localhost/myskyll';
mongoose.connect(mongoUri);
var db = mongoose.connection;
db.on('error', function () {
throw new Error('unable to connect to database at ' + mongoUri);
});
var app = express();
console.log("connection successfull");
app.configure(function(req,res){
app.use(express.bodyParser());
});
app.use(express.static(__dirname + "/" ));
require('./models/InquiryDetails');
require('./routes/Inquiry');
app.listen(3000);
console.log('Listening on port 3000...');
index.html:
<form method="post" id="form1" action="InquiryDetails">
Your Name:<span class="imp">*</span><br/><input type="text"
name="name" placeholder="Firstname Lastname" class="textbox"
autofocus required pattern="[A-Za-z-0-9]+\s[A-Za-z-'0-9]+"
title="'Firstname' <space> 'Lastname'"/> <br/><br/>
Email:<span class="imp">*</span><br/><input
type="email" name="email" placeholder="Email" class="textbox"
required/><br/><br/>
city:<span class="imp">*</span><br/><input type="text" name="city"
placeholder="city" class="textbox" required/><br/><br/>
State/Country:<span class="imp">*</span><br/>
<input type="text" name="country"
placeholder="State/Country" class="textbox" required /><br/>
<br/>
School/Institution:<span class="imp">*</span><br/><input
type="text" name="school" placeholder="Your School or
Institution" c lass="textbox" required /><br/><br/>
Your Profession:<br/><input type="text" name="profession"
placeholder="Profession" class="textbox"><br/><br/>
Phone:<br/><input type="text" name="phone" placeholder="Phn. no.
with country code" class="textbox" pattern="\+[0-9]+" title="Only
digits" /><br/><br/>
<input type="submit" value="Submit"
class="btn3"/>
<input type="reset" value="Clear" class="btn3" />
</form>
I have tried in postman API client to post the data but it shows 404 status while posting the data.
Do I have any problem in my code?
Any suggestion will be appreciated!
You are creating multiple app objects. One in app.js and a different one in routes/Inquiry.js.
For this type of application, you will want to be using only one app object that you share with anyone who needs it because only one of them is actually registered with your web server and is being used.
That is likely why your app.post() handler is not working because it's registered on the wrong app object - the one that is not connected to a live server.
There are several other things that look incorrect in the code:
The third argument to an app.post() callback is a next() function reference, not the err that you have declared and are testing.
You are doing require('./models/InquiryDetails'); and that module exports some things, but you are not assigning the result of the require to anything so those exports are unusable.
You are initializing the connect module, but if you are using a recent version of Express that module is no longer needed as the functionality it used to provide for Express is now built into Express.

Resources