1

I have a problem with Express body-parser in Node.js

I have inputs like this:

<input id="personEmail1" type="email" name="person[0][email]" placeholder="Email1" class="form-control">
<input id="personEmail2" type="email" name="person[1][email]" placeholder="Email2" class="form-control">

After when I submit my form I got this in my console.log:

{ 'person[0][email]': 'info@sss.sss', 'person[1][email]': 'info@ggg.ggg' }

But I want it to be parsed in json format:

{ person: [{email: 'info@sss.sss'}, {email: 'info@ggg.ggg'}] }

What I'm doing wrong?

Artem Kashin
  • 83
  • 2
  • 7
  • I have the same issue. The answer in this question http://stackoverflow.com/questions/4295782/how-do-you-extract-post-data-in-node-js, Instead of getting `request.body.user.name`, I got {"user[name]", '...'} – Rob Lao Mar 02 '15 at 14:46

4 Answers4

8

for express version 4.x when you need to manually install body-parser and multer, and you want to get nested properties from the post, e.g. data[test] in the form of req.body.data.test, you need to set:

app.use(bodyParser.urlencoded({ extended: true }));
may215
  • 330
  • 6
  • 13
1

You are using the Express body-parser middleware bracket notation correctly. But, as an example of what can be done...

Using this view:

<form method="post">
    <label for="person_email_1">Email address 1</label>
    <input id="person_email_1" name="person[0][email]" type="email" value="email1@example.com"> <br>

    <label for="person_email_2">Email address 2</label>
    <input id="person_email_2" name="person[1][email]" type="email" value="email2@example.com"> <br>

    <button type="submit">Submit v1</button>
</form>
<br>
<form method="post">
    <label for="person_email_1">Email address 1</label>
    <input id="person_email_1" name="person[email][0]" type="email" value="email1@example.com"> <br>

    <label for="person_email_2">Email address 2</label>
    <input id="person_email_2" name="person[email][1]" type="email" value="email2@example.com"> <br>

    <button type="submit">Submit v2a</button>
</form>
<br>
<form method="post">
    <label for="person_email_1">Email address 1</label>
    <input id="person_email_1" name="person[email]" type="email" value="email1@example.com"> <br>

    <label for="person_email_2">Email address 2</label>
    <input id="person_email_2" name="person[email]" type="email" value="email2@example.com"> <br>

    <button type="submit">Submit v2b</button>
</form>
<br>
<form method="post">
    <label for="person_email_1_address">Email address 1</label>
    <input id="person_email_1_address" name="person[emailAddresses][0][address]" type="email" value="email1@example.com">
    <input id="person_email_1_description" name="person[emailAddresses][0][description]" type="text" value="lorem ipsum 1"> <br>

    <label for="person_email_2_address">Email address 2</label>
    <input id="person_email_2_address" name="person[emailAddresses][1][address]" type="email" value="email2@example.com">
    <input id="person_email_2_description" name="person[emailAddresses][1][description]" type="text" value="lorem ipsum 2"> <br>

    <button type="submit">Submit v3</button>
</form>

...and this post handler:

function postHandler(req, res) {
    console.log(JSON.stringify(req.body)); // show in console
    res.send(req.body); // show in browser
}

Version 1 (your version, which works for me, and returns your desired result) req.body:

{
  "person": [
    {"email": "email1@example.com"},
    {"email": "email2@example.com"}
  ]
}

Versions 2a & 2b (an array of strings, with/without index number) req.body:

{
  "person": {
    "email": [
      "email1@example.com",
      "email2@example.com"
    ]
  }
}

Version 3 (an array of objects) req.body:

{
  "person": {
    "emailAddresses": [
      {
        "address": "email1@example.com",
        "description": "lorem ipsum 1"
      },
      {
        "address": "email2@example.com",
        "description": "lorem ipsum 2"
      }
    ]
  }
}

I've personally used versions 2 & 3 on a node/Express/jquery/Bootstrap line of business app where a person or business account can have unlimited telephone numbers, email addresses, and URLs. The body-parser bracket notation made it stupid easy.

1

Even though you've used valid Javascript syntax for your keys, they are still just strings and no JSON parser will attempt to call eval on them.

However, JSON already has a concept of arrays, which should work in the way you are expecting them to.

It would be useful to show us the code in which the call to console.log happens. But I would guess that instead, you need to rethink the naming convention for your field names.

<input id="personEmail1" type="email" name="personEmail1" placeholder="Email1" class="form-control">
<input id="personEmail2" type="email" name="personEmail2" placeholder="Email2" class="form-control">

Then create the Javascript object from that data.

function handler(req, res) {
   var people = [
     { email: req.body.personEmail1 },
     { email: req.body.personEmail2 }
   ];

   console.log(people[0]); // person 1
   console.log(people[1]); // person 2
   console.log(people);    // both people
}
Dan Prince
  • 29,491
  • 13
  • 89
  • 120
0

I used this https://github.com/macek/jquery-serialize-object to serialize my form as JSON. It parses data as I want and it's easy to use.

    $.ajax({
      type: 'post',
      data: $form.serializeJSON(),
      contentType: 'application/json',
      url: $url,
      success: function (result) { ... }
    });

I think this is the easyest

Artem Kashin
  • 83
  • 2
  • 7