How to read/parse Array in form-data node js - javascript

Please check the above image, I am trying to read this in Node Js. I am using express js and have tried debugging req.body. It is returning an empty object {}.
I am using app.use(bodyParser.json({ extended: true })); . To read body but unable to read the data.
I can parse/read json object which are sent in raw(json) format
Edit:
Added multer
But Still Return empty object {}
router.post('/array', uploads.none(), (req, res, next) => {
console.log(req.body)
})

bodyParser.json is used to parse application/json content type. The solution is to use multer middleware to parse form-data content type.
https://www.npmjs.com/package/multer

Related

Request post return an empty object in NODE.JS

I don't know why but i try to send an object in my back. I can find good information in my network's payload but my req.body return everytime an empty object
my probleme
add app.use(express.json());
express.json() is a middleware that allows express to recognise the json data in request object.
Also your controller is not sending any response back, for that use:
app.post("/", (req, res) => {
res.status(200).json({"data" : req.body});
}

ExpressJS request body is empty if i don't use multer

I have this very strange issue with my express app, i simply want to access req.body data that are send through post request via form-data but unfortunately i get undefined error when i try to access those values in request.body but what is strange about this is if i use multer middleware (i used this on another route to upload files) i don't get this error.
i have configured default body parser provided by express.
//body pharser
app.use(express.json());
app.use(
express.urlencoded({
extended: true,
})
);
//multer configuration
const ImageUpload = multer({
storage: storage,
limits: { fileSize: 4194304 },
fileFilter: Imagfilter,
});
//this will return undefined
app.post("/available",(req, res) => {
console.log(req.body.name);
}
//but this will return the value without any issues
app.post(
"/available",
ImageUpload.fields([
{ name: "nicImageFront", maxCount: 1 },
{ name: "nicImageBack", maxCount: 1 },
]),
(req, res) => {
console.log(req.body.name);
}
There's nothing strange about that.
FormData objects generate multipart requests. They have to, it is how they support file uploads.
The FormData interface provides a way to easily construct a set of key/value pairs representing form fields and their values, which can then be easily sent using the XMLHttpRequest.send() method. It uses the same format a form would use if the encoding type were set to "multipart/form-data".
Multer is designed to parse multipart requests.
The urlencoded middleware is designed to parse urlencoded requests, not multipart requests.
The json middleware is designed to parse JSON encoded requests, not multipart requests.

Polymer: making JSON ajax requests to NodeJS backend

I'm trying to test using NodeJS as a backend api for a Polymer front end. On the Polymer side, I have this iron-ajax element:
<iron-ajax
id='test-req'
url='http://localhost:9090/backend-test'
handle-as='text'
on-response='testRsp'
body='{"data":"stuff"}'>
</iron-ajax>
The testRsp handler simply logs the response text to the console. On the backend, this is my route:
app.get('/backend-test', function(req, res){
res.send(req.body)
console.log(req.body)
}
As you can see, all it does is respond with the raw request, and log the request on the backend. Both sides as expected have the same result, but unfortunately the result is just {}.
Now, I also tried sending the json in via the params attribute instead of the body attribute of the iron-ajax element, and on the backend I used the deprecated req.param() function like so: req.param('data'), and that correctly prints out stuff on both the browser and the backend. However, since it is deprecated, I'm trying to avoid that method.
Any suggestions?
Edit: I figured this extra piece of info would be helpful. When I log req.originalUrl on the backend when passing the json in 'params', I get /backend-test?data=stuff. When passing in 'body', it's just /backend-test.
I also want to note that I have tried variations of the bodyParser middleware as well:
->app.use(bodyParser.json()) (outcome as noted above)
->app.use(bodyParser.text()) (same)
->not using bodyParser at all (prints undefined as expected based on the express docs)
->app.use(bodyParser.text()); app.use(bodyParser.urlencoded({ extended: true })); (same output as json() and text(); taken from the req.body docs).
Edit2 Thanks AP. I have been putting the use statements before any route definitions, like so:
// Create Express object, enable CORS
var app = express()
app.use(bodyParser.json())
app.use(cors())
// Route definitions
app.post('/backend_test', function(req, res){
res.json(req.body)
console.log(req.body)
})
app.listen(9090, function() {
console.log('App started, listening on port 9090')
})
I also updated my iron-ajax element to explicitly make a post rather than get, and set content type as json, but no dice. I'm still getting only {} out the other side:
<iron-ajax
id='test-req'
url='http://localhost:9090/backend_test'
content-type="json"
method="post"
handle-as='json'
on-response='testRsp'
body='{"data":"stuff"}'>
</iron-ajax>
Edit3 I found the mistake with my update, content-type needed to be application/json, not just json. That got it working finally. Thanks!
Your middleware should be initialized before your routes, and should somewhat resemble this:
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
In terms of the Polymer Implementation, if you are sending JSON data, according to the docs your element should also contain:
<iron-ajax content-type='json'>
There is also a demo-repository that show's an example MEAN stack server running polymer as it's front-end. Which I believe ties into your question as well?
PS. Youtube-Black is a more comprehensive example.
Edit:
I just realized you're missing the method attribute on your Polymer element. Without that, you are sending a GET request! Make sure to use your element like so, in addition to your other props:
<iron-ajax content-type='json' method='post'>

Error when doing post with express JS

I am testing the post method to create a todo item as follows. I am using postman in chrome to simulate the post method call. However, it does not work and gives me the below error. I suspect something is wrong with the way body-parser library is working. What am I doing wrong here?
1 SyntaxError: Unexpected token b
2: at parse (/Users/zack/mydrive/proj/express-demo/node_modules/body-parser/lib/types/json.js:83:15)
3: at /Users/zack/mydrive/proj/express-demo/node_modules/body-parser/lib/read.js:116:18
4: at invokeCallback (/Users/zack/mydrive/proj/express-demo/node_modules/body-parser/node_modules/raw-body/index.js:262:16)
5: at done (/Users/zack/mydrive/proj/express-demo/node_modules/body-parser/node_modules/raw-body/index.js:251:7)
6: at IncomingMessage.onEnd (/Users/zack/mydrive/proj/express-demo/node_modules/body-parser/node_modules/raw-body/index.js:308:7)
7 at IncomingMessage.emit (events.js:104:17)
8 at _stream_readable.js:908:16
Code:
var express = require('express');
var app = express();
var handlebars = require('express-handlebars');
var bodyParser = require('body-parser');
//MIDDLEWARE
app.engine('handlebars', handlebars({defaultLayout: 'main'}));
app.set('view engine', 'handlebars');
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({
extended: true
}));
// TODOS
var todos = [
{ body: "take out the trash",completed: false},
{ body: "Do the laundry",completed:true},
{ body: "Make a screencast",completed:false}
]
app.post('/todos', function (req, res){
console.log("todo:", req.body);
var todo = req.body;
console.log("todo:"+todo);
todos.push(todo);
res.status(200).json(todo);
res.send('OK')
})
Further I observe that the problem is because of this line.
app.use(bodyParser.json());
Are you sure you are sending the request as JSON? Make sure you've selected it in Postman - https://imgur.com/j0M7TEX.
If that didn't work, you can try the following -
...
app.post('/todos', function (req, res){
console.log("todo:", req.body);
var todo = req.body;
console.log("todo:"+todo);
todos.push(todo);
// Only try to send a single response.
res.json(todo);
});
It looks like you were trying to send two responses, one containing JSON, and another with text/plain ('Ok').
http://expressjs.com/fr/api.html#res.json
It seems like your program is trying to interpret the post data as json data - and generating an error when it trys to parse the request data which is probably url-encoded.
Perhaps consider sending your data in json format. You will have to set the request headers to indicate the datatype is json. See this answer for an example:
Angular JS POST request not sending JSON data
I just created a new session in postman and it started working. I am not sure if there is a caching effect but it works now. I did not make any code change at all. Posting this as the solution now.
Just don't put quotes on your JSON value.
Not "okay2" but just okay2.
I think that postman adds the quotes himself if needed and in this case creates ""okay2"" which isn't valid JSON.
By the way you can test by clicking on the "row" radio button and write your own JSON.

Trouble extracting request data in Node.js (Express)

I'm trying to extract data from a request (in this case a POST) and am having trouble. I'm doing so using the body-parser module. Below is a portion of my code (note I am using ES6 syntax):
let bodyParser = require('body-parser')
var urlEncodedParser = bodyParser.urlEncoded({extended: true})
app.post('*', setFileMeta, setDirDetails, urlEncodedParser, (req, res, next) => {
async ()=> {
if (!req.stat) return res.send(405, 'File does not exist')
if (req.isDir) return res.send(405, 'Path is a directory') // This is an advanced case
await fs.promise.truncate(req.filePath, 0)
req.pipe(fs.createWriteStream(req.filePath)) // Filepath is a file
// This below line is where I need the body
sendToClients('update', req.url, 'file', req.body, Date.now())
res.end()
}().catch(next)
})
For the actual extraction of the data using body-parser, urlEncoded is the only way I was able to successfully do it (the data is just a string for now), and it's giving me in the format {content: ''} where content is the actual string I'm using. This isn't ideal but it works in this simple. However, this is breaking the createWriteStream(req.filePath) as seen above - the file is created, but there is no content.
There must be something obvious that I'm doing incorrectly, as I'm new to Node and Express. Since I wrote the majority of this with the help of an instructional video, my gut tells me it's the body extraction part since I'm doing that on my own.
body-parser exhausts (fully reads) the request stream in order to parse the incoming parameters, so there's no data left in the request stream to write to your file.
It seems to me that you're trying to implement file uploads. In that case, you probably want to use a module like multer instead of body-parser.

Categories

Resources