Björn C
Björn C

Reputation: 4008

Is it necessary to create nested jSON objects before using it?

I think I've seen how to create a JSON object without first preparing it. This is how i prepare it:

obj = {
  0:{
    type:{}
  },
  1:{},
  2:{}
};

Now I think I can insert a value like: obj.0.type = "type0"; But I'd like to create it while using it: obj['0']['type'] = "Type0";.

Is it possible, or do I need to prepare it? I'd like to create it "on the fly"!

EDIT

I'd like to create JS object "On the fly".

var obj = {};
obj.test = "test"; //One "layer" works fine.
obj.test.test = "test" //Two "layers" do not work... why?

Upvotes: 3

Views: 220

Answers (4)

user663031
user663031

Reputation:

obj = {
  0:{
    type:{}
  },
  1:{},
  2:{}
};

Now i think i can insert value like: obj.0.type = "type0";

I guess you mean "assign" a value, not "insert". Anyway, no, you can't, at least not this way, because obj.0 is invalid syntax.

But I'd like to create it while using it: obj['0']['type'] = "Type0";

That's fine. But you need to understand you are overwriting the existing value of obj[0][type], which is an empty object ({}), with the string Type0. To put it another way, there is no requirement to provide an initialized value for a property such as type in order to assign to it. So the following would have worked equally well:

obj = {
  0:{},
  1:{},
  2:{}
};

Now let's consider your second case:

var obj = {};
obj.test = "test"; //One "layer" works fine.
obj.test.test = "test" //Two "layers" do not work... why?

Think closely about what is happening. You are creating an empty obj. You can assign to any property on that object, without initializing that property. That is why the assignment to obj.test works. Then in your second assignment, you are attempting to set the test property of obj.test, which you just set to the string "test". Actually, this will work--because strings are objects that you can set properties on. But that's probably not what you want to do. You probably mean to say the previous, string value of obj.test is to be replaced by an object with its own property "test". To do that, you could either say

obj.test = { test: "test" };

Or

obj.test = {};
obj.test.test = "test";

Upvotes: 1

Nina Scholz
Nina Scholz

Reputation: 386654

Is it necessary to create nested objects before using it?

Yes it is, at least the parent object must exist.

Example:

var object = {};

// need to assign object[0]['prop'] = 42;

create the first property with default

object[0] = object[0] || {};

then assign value

object[0]['prop'] = 42;

var object = {};

object[0] = object[0] || {};
object[0]['prop'] = 42;

console.log(object);

Create object with property names as array

function setValue(object, keys, value) {
    var last = keys.pop();
    keys.reduce(function (o, k) {
        return o[k] = o[k] || {};
    }, object)[last] = value;
}

var object = {};

setValue(object, [0, 'prop'], 42);
console.log(object);

Upvotes: 0

Nenad Vracar
Nenad Vracar

Reputation: 122057

You could create your own function that takes key as string and value and creates and returns nested object. I used . as separator for object keys.

function create(key, value) {
  var obj = {};
  var ar = key.split('.');

  ar.reduce(function(a, b, i) {
    return (i != (ar.length - 1)) ? a[b] = {} : a[b] = value
  }, obj)

  return obj;
}

console.log(create('0.type', 'type0'))
console.log(create('lorem.ipsum.123', 'someValue'))

Upvotes: 0

Andrea
Andrea

Reputation: 3440

You are creating a plain object in JavaScript and you need to define any internal attribute before using it.

So if you want to set to "Type0" an attribute type, inside an attribute 0 of an object obj, you cannot simply:

obj['0']['type'] = "Type0";

You get a "reference error". You need to initialize the object before using it:

var obj = {
  0: {
    type: ""
  }
};

obj['0']['type'] = "Type0";

console.log(obj['0']['type']);

Upvotes: 0

Related Questions