How to get arrays / objects submitted via form in sails.js (using multipart / form-data enctype)

I place information on my forms in accordance with my models, which greatly simplifies the work on the backend, but I can’t find out how to get arrays or objects (or a combination of them) in Sails.js

Assuming I have this form

NOTE. Full support for "multipart / form-data".

<form action="/articles" method="post" enctype="multipart/form-data"> <input type="file" name="status" value="published"> <!-- Entry 0 --> <input(type="text" name="entries[0][title]" value="Entry 1") <input(type="text" name="entries[0][content]" value="Entry 1 Content...") <!-- Entry 1 --> <input(type="text" name="entries[1][title]" value="Entry 2") <input(type="text" name="entries[1][content]" value="Entry 2 Content...") <!-- images --> <input type="file" name="images[]"> <input type="file" name="images[]"> </form> 

I expect to get such an object in req.params.all () obj

 { status: 'published', entries: [ {title: 'Entry 1', content: 'Entry 1 Content...'}, {title: 'Entry 2', content: 'Entry 2 Content...'} ] } 

Now when I call req.params.all() / req.body I get:

 { status: 'published', 'entries[0][title]': 'Entry 1' 'entries[0][content]': 'Entry 1 Content...' 'entries[1][title]': 'Entry 2' 'entries[1][content]': 'Entry 2 Content...' 'entries[0][title]': 'Entry 1' } 

Calling req.file('images[]') gives the correct behavior. I am checking the ._files property of what is returned by this fn and showing my 2 images. Using brackets here seems really strange, but what is it.

I assume this is due to what I get with req.params.all () I can analyze it again, but it will be hacked and fragile if something changes in the future. In any case, this is a common template in any web application and is supported by many languages ​​and frameworks, so it’s really strange for me that it seems impossible to get what I need, only with simple sails.js functionality, so I assume that I I don’t do something the way I should, or that I am missing something, please point me in the right direction, and if Sails doesn’t actually support this basic nesting behavior, how should I continue?

Sending raw content using Javascript is not an option here (if this is not possible), as suggested in the third answer in this question: Is it possible to create more complex models in Sailsjs By doing this this way, at least for text fields, I get the correct output , not sure about the images, as I tested through the postman with rawdata.

Edit: So far, I have tried to change the skipper body parser in config / http.js as follows:

 bodyParser: { fn: require('body-parser').urlencoded, options: {extended:true} } 

But it made my server useless, it really started, but it didn’t answer a single request, I’m not sure why (even using our skipper example that you just need to uncomment does not work).

Since the skipper is based on bodyparser, I modified the skipper module.js module to check what is happening.

 var URLEncodedBodyParser = connect.urlencoded({extended:true}) 

But this did not work, I get the same result as the beginning, even installing body-parser and using it instead of the connect.urlencoded parser having no effect.

Edit 2:. As @robertklep stated, using the form data without repeated work, but of course I lose the ability to upload files, which is really important, and the reason I put it in the sample form.

Edit 3:. To complement the accepted answer, if someone needs it, here is what I did:

In config/http.js

 middleware: { order: [ // some middleware 'bodyParser', 'qsBodyParser', // more middleware ], qsBodyParser: require('../api/middleware/qsBodyParser') } 

And in api/middleware/qsBodyParser

 Qs = require('qs'); qsBodyParser = function(req, res, next) { if req.is('multipart/form-data'){ req.body = Qs.parse(req.body); } return next(); }; module.exports = qsBodyParser; 
+7
javascript express
source share
1 answer

The exclusive version of skipper depends on connect@2.25.0 , which depends on body-parser@1.6.0 , which does not handle how to send arrays of forms / objects.

An example of your form is as follows (using extended : true ):

 { "entries" : [{ "content" : "Entry 1 Content..." }, { "content" : "Entry 2 Content..." }] } 

The latest version ( body-parser@1.13.3 ) works as expected, so you need to somehow connect it to skipper .

EDIT : This comment seems to suggest that using multipart/form-data will disable the parsing of the array (/ object?) In general.

EDIT # 2 : you can manually parse req.body with qs , which seems to take an object as an argument:

 var qs = require('qs'); var obj = qs.parse({ status: 'published', 'entries[0][title]': 'Entry 1', 'entries[0][content]': 'Entry 1 Content...', 'entries[1][title]': 'Entry 2', 'entries[1][content]': 'Entry 2 Content...', }); // obj is now: // { status: 'published', // entries: // [ { title: 'Entry 1', content: 'Entry 1 Content...' }, // { title: 'Entry 2', content: 'Entry 2 Content...' } ] } 
+6
source share

All Articles