2

I have a string like this:

string = '{ "key": [
  { "foo": "bar" }
] }';

This string is converted into a JSON object by doing

json = $.parseJSON(string);

and then it looks like this:

{ "key":
  { "0":
    { "foo": "bar" }
  }
}

So it seems like the array was converted into a hash.

The desired outcome would instead be:

{ "key": [
  { "foo": "bar" }
] }

What's the best way to achieve this? Background: I am posting JSON data to a URL but need the array to stay intact so the recipient can parse it accordingly.

Update

Here is what I see in a console of Chrome 37.0.2062.120 and jQuery 1.11.1:

enter image description here

It looks like an array, but is really just another hash with a key of "0". Or am I getting something wrong?

Update 2

After converting the string into a JSON update I am posting it to a url:

$.ajax({
    url: 'http://test.com',
    data: json,
    dataType: 'jsonp',
    type: 'post'
  })

where it arrives as

{ "key":
  { "0":
    { "foo": "bar" }
  }
}
Dennis Hackethal
  • 13,662
  • 12
  • 66
  • 115
  • 3
    Your string isn't valid Json. I get "*Uncaught SyntaxError: Unexpected token :*". If you start with a valid Json string like `'{"key": [{ "foo": "bar" }]}'`, you'll get the expected result. – p.s.w.g Sep 15 '14 at 21:16
  • Sorry, that was just a typo. Updated my question. – Dennis Hackethal Sep 15 '14 at 21:22
  • Sorry, but I still can reproduce the behavior. When I parse that string, I get exactly the desired output. Are you sure it's not just an issue with how you're displaying the result? – p.s.w.g Sep 15 '14 at 21:25
  • Yes, where are you "seeing" this output? – OneHoopyFrood Sep 15 '14 at 21:25
  • I have updated my question with a screenshot from my console. – Dennis Hackethal Sep 15 '14 at 21:32
  • In Javascript, everything is a hash of key and value which is why you see hash for Arrays with index as hash key and value as object. – Liam Sep 15 '14 at 21:33
  • Arrays are objects and each element is a property of that object. You can tell that `key` is an array because its prototype is `Array.prototype` (also it has a `length` property, so it certainly does not look like `{ "0": { "foo": "bar" } }`). – Felix Kling Sep 15 '14 at 21:35
  • 3
    Your screenshot shows you that it is indeed an array, you're just confused by the keys. Try to do `JSON.stringify($.parseJSON(string))` Remember that Array extends Objects so they look like objects too, with additional properties like length, forEach, push... – Ruan Mendes Sep 15 '14 at 21:35
  • @JuanMendes That looks promising. The issue is that I am posting the JSON object to a URL and it arrives there as `{ "key": { "0": {...} } }` as opposed to `{ "key": [...] }`. Is there a way to change that? – Dennis Hackethal Sep 15 '14 at 21:38
  • @Charles Where is the code that is doing the encoding? You should post that – Ruan Mendes Sep 15 '14 at 21:38
  • @Charles is `string` the same variable as `string = '{ "key": [ { "foo": "bar" } ] }';` ? You should show more context. Where is string coming from? – Ruan Mendes Sep 15 '14 at 21:45
  • @JuanMendes Sorry, I am posting `json` of course. – Dennis Hackethal Sep 15 '14 at 21:46
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/61308/discussion-between-juan-mendes-and-charles). – Ruan Mendes Sep 15 '14 at 21:47

3 Answers3

2

When you send the AJAX, you can encode the JSON yourself

For JSONP, use

var json = '{ "key": [  { "foo": "bar" }] }';
var jsObj = $.parseJSON(json);
$.ajax({
    url: 'http://test.com',
    // You have to convert your JS object into a JSON string on your own
    // jQuery will convert them into form encoded values if you leave it as an object
    // But you want to send your whole JSON as one of the keys, 
    // so do use an object around your json to specify the the name of the
    // key value pair containing the JSON
    data: {myKey: JSON.stringify(jsObj)},
    dataType: 'jsonp',
    // The answer at http://stackoverflow.com/questions/6410810/rails-not-decoding-json-from-jquery-correctly-array-becoming-a-hash-with-intege
   // suggests you may need this for Rails to understand it
    contentType: 'application/json'
    // type can't be post for JSONP
    // type: 'post'
  })

For a POST, use

$.ajax({
    url: '/my/url/',
    // For POST, you can post the entire string, converting it on your own
    data: JSON.stringify(jsObj),
    type: 'POST'
  })
Ruan Mendes
  • 90,375
  • 31
  • 153
  • 217
1

In Javascript, everything is a hash of key and value which is why you see hash for Arrays with index as hash key and value as object.

This works for me.

var jsonStr = '{ "key": [{ "foo": "bar" }] }';

var obj = $.parseJSON(jsonStr);
if (obj.key instanceof Array) {
alert('value is Array! and its length is > '+obj.key.length);
} else {
alert('Not an array');
}

http://jsbin.com/rifinu/1/

Liam
  • 2,837
  • 23
  • 36
0

On the one hand, that all needs to be wrapped up in braces like so

string = '{"key": [
  { "foo": "bar" }
]}';

Which is going to let jQuery parse it with jQuery.parseJSON(string)

It's wrapped up in an array, which is why you're getting an array. I'm guessing here, but is what you really want:

string = '{"key": 
  { "foo": "bar" }
}';

so that you can access "bar" by just hitting array['key']['foo']? If so, remove those brackets.

Camilo Payan
  • 181
  • 7