3

On the webpage I am POSTing some JSON using jQuery:

$.post('/url', data);

My data is a javascript object that contains some values and an array. JSON.stringify(data) looks like:

{"favoriteAnimal":"piglet", "okayAnimals":["cats","dogs"]} 

I'm consuming this JSON in a NodeJS webapp using ExpressJS (which is wired up with the body-parser middleware). I can retrieve the favorite animal like req.body.favoriteAnimal and it gives me the string piglet which is all fine and dandy.

But how do I access the values in the array?

req.body.favoriteAnimal // piglet
req.body.okayAnimals // undefined
req.body.okayAnimals[] // syntax error

This works...

req.body['okayAnimals[]']

...but smells fishy. It also won't return an array if the original data that is being POSTed contains only one element in its array (it just returns a single string).

Is there something going on with the the jQuery encoding of the JSON or something going on with the decoding in ExpressJS that's preventing me from accessing it like req.body.okayAnimals and getting an array every time?

3
  • hmmm... that doesn't sound right at all.... req.body.okayAnimals shouldn't be undefined given that json string. Commented Oct 23, 2014 at 20:33
  • Are you sure data is json (a string) and not an object? As a matter of fact, i'm positive it's an object and not a string, because that explains the behavior you are seeing. It gets turned into form parameters if it's an object: favoriteAnimal=piglet&okayAnimals[]=cats&okayAnimals[]=dogs Commented Oct 23, 2014 at 20:34
  • typeof(data) returns an object so you are correct, it is not a string Commented Oct 23, 2014 at 21:10

2 Answers 2

1

JavaScript objects and JSON are two very differen things, which is the root of the problem you are seeing. What you are passing to $.post() is actually an object, not json, and is therefore being converted to a paramstring by jQuery before being sent to node. In this case, the paramstring is:

favoriteAnimal=piglet&okayAnimals[]=cats&okayAnimals[]=dogs

which of course explains why an okAnimals[] property exists on the body.

I'm surprised that the middleware you are using to parse the body isn't picking that up properly, but regardless you should instead pass a json string to $.post if you want to send it as is.

$.post('/url', JSON.stringify(data));
Sign up to request clarification or add additional context in comments.

Comments

1

Kevin's answer almost got me there.

$.post('/url', JSON.stringify(data)) will send a string which is one step closer. Unfortunately jQuery's $.post sets the wrong header

Content-Type:application/x-www-form-urlencoded; charset=UTF-8

which ExpressJS's body-parser will not handle appropriately. You end up with

req.body={"{\"favoriteAnimal\":\"piglet\",\"okayAnimals\":[\"cats\",\"dogs\"]}":""}

I rewrote how I was sending the data.

$.ajax({
  url: '/url',
  type: 'POST',
  data: data,
  contentType: 'application/json; charset=utf-8',
  dataType: 'json'
})

I saw that my browser was sending the correct headers

Content-Type:application/json; charset=UTF-8

And observed

req.body={"favoriteAnimal":"piglet","okayAnimals":["cats","dogs"]}

1 Comment

Thanks for posting! For the past hour I've been searching for a solution to this same problem. I couldn't figure out the right Google terms. Now I learned that I was so accustomed to just passing string data as object/json I forgot they weren't the same thing (or context, or whatever).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.