6

I have a JavaScript object.

var obj = { Id: "100", Name: "John", Address: {Id:1,Name:"Bangalore"} }
var dataToRetrieve= "Name";

function GetPropertyValue(object,dataToRetrieve){
      return obj[dataToRetrieve]
}
var retval = GetPropertyValue(obj,dataToRetrieve)

This works fine. But if I try to get the value of property value of "Address.Name" ,

Like : var dataToRetrieve = "Address.Name"; it shows undefined.

Note : The property variable is set by user from HTML And it can be changed according to user requirement(which property value he wants).

What I want to achieve :

1) If dataToRetrieve = "Name" , it should give me "John",

2) If dataToRetrieve = "Id" , it should give me "100",

3) If dataToRetrieve = "Address.Name" , it should give me "Bangalore",

4) If dataToRetrieve = "Address.Id" , it should give me 1

Plunkr Here : PLUNKR

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Bimal Das
  • 1,882
  • 5
  • 28
  • 53

4 Answers4

27

Use reduce() method

var obj = {
  Id: "100",
  Name: "John",
  Address: {
    Id: 1,
    Name: "Bangalore"
  }
}

function GetPropertyValue(obj1, dataToRetrieve) {
  return dataToRetrieve
    .split('.') // split string based on `.`
    .reduce(function(o, k) {
      return o && o[k]; // get inner property if `o` is defined else get `o` and return
    }, obj1) // set initial value as object
}


console.log(
  GetPropertyValue(obj, "Name"),
  GetPropertyValue(obj, "Id"),
  GetPropertyValue(obj, "Address.Name"),
  GetPropertyValue(obj, "Address.Id"),
  GetPropertyValue(obj, "Address.Idsd"),
  GetPropertyValue(obj, "Addre.Idsd")
)


For older browser check polyfill option of reduce method.
Pranav C Balan
  • 113,687
  • 23
  • 165
  • 188
  • 2
    It is a good idea to add protection against `undefined` values, like in the answer above. – Renato Gama May 29 '16 at 13:59
  • it works good. 1 question : if obj containing some array property, will it work? like var obj = { Id: "100", Name: "John", Address: [{Id:1,Address:"Bangalore"},{Id:2,Address:"Mysore"}] } and then call the function like GetPropertyValue(obj, "Address[0].Name") ? – Bimal Das May 29 '16 at 14:08
  • 1
    @BimalDas : `GetPropertyValue(obj, "Address.0.Name") ` will work – Pranav C Balan May 29 '16 at 14:14
  • 1
    Here is a version that allows bracket notation & property names with spaces as well as validating the inputs: https://it.knightnet.org.uk/kb/node-js/get-properties/ – Julian Knight Jan 03 '19 at 14:04
7

Use following function:

var obj = { Id: "100", Name: "John", 
            Address:  [{ Id:1, Name:"Bangalore" }, { Id:2, Name: "Mysore" } ] };

function GetPropertyValue(object, dataToRetrieve) {
    dataToRetrieve.split('.').forEach(function(token) {
      if (object) object = object[token];
    });
    
    return object;
}

console.log(
  GetPropertyValue(obj, "Address.0.Name"),
  GetPropertyValue(obj, "Address.1.Id"),
  GetPropertyValue(obj, "Name"),
  GetPropertyValue(obj, "Id"),
  GetPropertyValue(obj, "Unknown"),
  GetPropertyValue(obj, "Some.Unknown.Property")
);
gevorg
  • 4,835
  • 4
  • 35
  • 52
2
 function GetPropertyValue(object,dataToRetrieve){
  var valueArray = dataToRetrieve.split(".");
  if (valueArray.length <= 1) {
    return object[valueArray];
  } else {
    var res;
    function browseObj(obj, valueArray, i) {
      if (i == valueArray.length)
        res = obj;
      else
        browseObj(obj[valueArray[i]], valueArray, i+1);
    }
    browseObj(object, valueArray, 0);
    return res;
  }
}
boehm_s
  • 5,254
  • 4
  • 30
  • 44
2

I had written a standard reusable Object method to access nested properties dynamically. It's like

Object.prototype.getNestedValue = function(...a) {
  return a.length > 1 ? (this[a[0]] !== void 0 && this[a[0]].getNestedValue(...a.slice(1))) : this[a[0]];
};

It will take dynamic arguments for the nested properties. If they are string type they are object properties if number type then they are array indices. Once you have this, your job becomes very easy. Let's see..

Object.prototype.getNestedValue = function(...a) {
  return a.length > 1 ? (this[a[0]] !== void 0 && this[a[0]].getNestedValue(...a.slice(1))) : this[a[0]];
};
var props = ["Address","Name"],
      obj = { Id: "100", Name: "John", Address: {Id:1,Name:"Bangalore"} },
      val = obj.getNestedValue(...props);
console.log(val);
// or you can of course do statically like
      val = obj.getNestedValue("Address","Name");
console.log(val);

You can see getNestedValue() and it's twin setNestedValue() working at https://stackoverflow.com/a/37331868/4543207

Community
  • 1
  • 1
Redu
  • 25,060
  • 6
  • 56
  • 76