2

I'm trying to access a property of an object dynamically with a string. For example: ".id.public" -> anyObject["id"]["public"]

The problem - I don't know how many arguments I have (for example ".id" or ".id.public" or ".id.public.whatever".

I made a little workaround:

var currentSplit = anyObject;
var splitted = "id.public".split("\.");
splitted.forEach(function(s) { currentSplit = currentSplit[s]; });

When I try now to override the object property I will override the reference and not the object property.

currentSplit = "test";

I tried already stuff like anyObject["id.public"] = "test"; but it didn't work.

2
  • You can't access nested object properties with a string in javascript, you need some sort of helper function to do it for you, you could look at angulars $parse interface for some inspiration. Commented Aug 14, 2014 at 11:14
  • Two variables that share the same value doesn't mean you can change both variables by just assigning one. Do you intend to read a value at "id.public", or to write a value at "id.public" ? Does this answer work for you ? Commented Aug 14, 2014 at 11:18

3 Answers 3

2

The deep-get-set library does what you want:

function get (obj, path) {
  var keys = path.split('.');
  for (var i = 0; i < keys.length; i++) {
    var key = keys[i];
    if (!obj || !hasOwnProperty.call(obj, key)) {
      obj = undefined;
      break;
    }
    obj = obj[key];
  }
  return obj;
}

function set (obj, path, value) {
  var keys = path.split('.');
  for (var i = 0; i < keys.length - 1; i++) {
    var key = keys[i];
    if (deep.p && !hasOwnProperty.call(obj, key)) obj[key] = {};
    obj = obj[key];
  }
  obj[keys[i]] = value;
  return value;
}
Sign up to request clarification or add additional context in comments.

3 Comments

Personally I would avoid the names get and set because they can be operators by themselves; but otherwise this looks fine
Same for me, I just copied code from the library, in which set and get are locally defined and not exposed.
I think my solution is better, it does it in one ultra fast function and it does a lot more, it can even execute a method and walk any object that method returns, a lot smarter in one tiny box!
1

Yet another way for setting value

function setVal(obj, path, val){
    var paths = path.split('.'),
        curProp = obj;

    for(var i=0;i<paths.length-1;i++){
        curProp = curProp[paths[i]];
    }
    curProp[paths[i]] = val;

}

and use it like

setVal(anyObj, "id.public", 'newValue');

Comments

0

You can't do that without the help of a little code like this:

 var mapToProperty = function(obj, path, value) {
        if (!path) return obj;

        var parts = path.split("."),
           p = parts[0],
           v = (typeof obj[p] === "function") ? obj[p](value) : (parts.length !==1 || !value) ? obj[p] : (obj[p] = value), value ;
           if (parts.length == 1) return v;
               return mapToProperty(v, parts.slice(1).join("."), value);
}

// use it like this

var myvalue = mapToProperty(myObj, "address.street")

// you can map into your objects as far as you want. obj1.obj2.obj3.prop

// you can set as well :-)

mapToProperty(myObj, "address.street", "This is great!")

11 Comments

ReferenceError: func is not defined, also, where does it set value?
This function will also execute methods - for example pass it an object with a method that evaluates to something obj1.method()
Sorry copied from my libary missed that erorr, fixed.
pass the value in as per the paramters, obj, stringmap, value
OK, sorry this sets on methods, it is the way it was intended I can modify it so that it sets properties if a value is passed give me 5!
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.