4

I have been trying to parse nested JSON data and below is my code

var string = '{"key1": "value", "key2": "value1", "Key3": {"key31":"value 31"}}';
var obj = JSON.parse(string);
console.log(obj.key1)
console.log(obj[0]);

And this is the output

$ node try.js 
value
undefined

Why I am getting undefined for obj[0]? How to get value in this case, and also for nested key key31?

Update Now with the help from @SergeyK and others, I have modified my above code as follows

var string = '{"key1": "value1", "key2": "value2", "key3": {"key31":"value 31"}}';

var obj = JSON.parse(string);
var array = Object.keys(obj)

for (var i = 0; i < array.length; i++) {
    console.log(array[i], obj[array[i]]);
}

And the output is as follows

$ node try.js 
key1 value1
key2 value2
key3 { key31: 'value 31' }

But for {"key31":"value 31"} how would I access key key31 and get its value value 31?

Andreas
  • 5,393
  • 9
  • 44
  • 53
Joel Divekar
  • 187
  • 1
  • 4
  • 19
  • What value would you expect for `obj[0]`? – str Aug 23 '16 at 06:51
  • 1
    It is an hash, not an array. What do you expect when you write `obj[0]`? – Amiram Korach Aug 23 '16 at 06:51
  • 1
    JSON **Objects** (`{ ... }`) use key based indexes, which means if you want to get `"value"` you need to reference it by it's key: `obj["key1"]` or `obj.key1`, you can only used numeric indexes when using **Arrays**: `[ .. ]` – Paradoxis Aug 23 '16 at 06:54

6 Answers6

2

You just can't access named object property by index. You can use obj[Object.keys(obj)[0]]

Edit:

As @smarx explained in the comments, this answer is not suitable for direct access to the specific property by index due to Object.keys is unordered, so it is only for cases, when you need to loop keys/values of object.

Example:

var string = '{"key1": "value", "key2": "value1", "Key3": {"key31":"value 31"}}';
var obj = JSON.parse(string);
var keysArray = Object.keys(obj);
for (var i = 0; i < keysArray.length; i++) {
   var key = keysArray[i]; // here is "name" of object property
   var value = obj[key]; // here get value "by name" as it expected with objects
   console.log(key, value);
}
// output:
// key1 value
// key2 value1
// Key3 { key31: 'value 31' }
SergeyK
  • 1,522
  • 1
  • 13
  • 15
  • I don't think `Object.keys` guarantees any particular ordering, so there's no way to predict which key you would be accessing here, right? (So I can't see how this code would be useful.) – user94559 Aug 23 '16 at 06:57
  • There was nothing about ordering in the question if i have no any misunderstanding. It is suitable for looping trough object properties, for "getting value", not for direct access to the specific property. – SergeyK Aug 23 '16 at 07:03
  • 1
    The snippet you shared will give a random value from the object. (Random in the sense that it can't be predicted.) Do you actually think that will help the person who asked this question? – user94559 Aug 23 '16 at 07:05
  • Snippet i shared just shows how to access values, as it was requested. You can also use `Object.keys(obj)[0]` a key name, depends what do you want to do, right? – SergeyK Aug 23 '16 at 07:11
  • How do I loop keys values of the JSON object as I would be getting JSON object and would have no clue of the Key names – Joel Divekar Aug 23 '16 at 09:35
  • Thanks SergeyK. But can't we read it raw as a JSON instead of converting it to array ? – Joel Divekar Aug 23 '16 at 10:44
  • We do not converting it to array, we just get array of object's "property names", with `Object.keys()` method. Then we iterate through this array, so for every name we will get every value "by name" `var value = obj[key]`. – SergeyK Aug 23 '16 at 11:00
  • Thanks I read through my array of objects and I am able to get key value of top level i.e key1, key2 and key3 using obj[1] ... obj[3], but how do I get a value for "key31" as I am not able to do obj[2][0]. – Joel Divekar Aug 23 '16 at 11:37
  • You can do it going through the "levels" with recursive function i think. – SergeyK Aug 23 '16 at 12:53
  • @Sergeyk, please can you guide. Thanks – Joel Divekar Aug 24 '16 at 07:55
  • You must consider that this is only a concept of usage, not the bulletproof recipe. – SergeyK Aug 24 '16 at 08:26
  • Thanks for your help @SergeyK – Joel Divekar Aug 24 '16 at 14:23
2

When you tries to access

 console.log(obj[0]);

You are actually trying to refer element at very first memory location in an array, but var string is a hash not array. Thats why you are getting undefined.

Ashu Jha
  • 344
  • 2
  • 9
2

console.log(obj[0]) will display its value only if obj is an array. For example:

var obj = ["value","value2"];
console.log(obj[0]) --> value

With an object, you need to use the key as identifier.

For nested key key31:

console.log(obj.Key3.key31) --> value 31

Hope to be helpfull

aserrin55
  • 350
  • 5
  • 15
2

console.log(obj[0]); is giving undefined because obj is not an array. obj[0] will work only if obj is an array as we are accessing the first index element from an array.

Example :

var obj = ["val1","val2","val3"];

console.log(obj[0]); // val1

As per requirement :

var string = '{"key1": "value", "key2": "value1", "Key3": {"key31":"value 31"}}';
var obj = JSON.parse(string);
var keyArray = Object.keys(obj); // key1
console.log(obj[(keyArray[0])]); // value

working fiddle :

https://jsfiddle.net/kbwbspnk/

For nested property value you have to use . operator.

console.log(obj.Key3.key31); // value 31
Debug Diva
  • 26,058
  • 13
  • 70
  • 123
1

I have no idea what you want obj[0] to do, so I can't help with that.

To get the value for key31, use obj.Key3.key31, which, when logged, should yield value 31.

user94559
  • 59,196
  • 6
  • 103
  • 103
0

your variable (String) is not array its object in above case and you can not access using indexing like 0,1,2... ,you can access this with its key value name like key1,key2...

example: obj['key1'] $ value obj['Key3']['key31'] $ value 31