Eric Wu
Eric Wu

Reputation: 917

Retrieving JS' Object value without knowing it's name

This is a fairly common question here in SO, and I've looked into quite a few of them before deciding to ask this question.

I have a function, hereby called CheckObjectConsistency which receives a single parameter, an object of the following syntax:

objEntry:
{
        objCheck: anotherObject,
        properties: [
            {
                //PropertyValue: (integer,string,double,whatever), //this won't work.
                PropertyName: string,
                ifDefined: function,
                ifUndefined: function
            }
            ,...
        ]
}

What this function does is... considering the given parameter is correctly designed, it gets the objCheck contained within it (var chk = objEntry.objCheck;), It then procedes to check if it contains the properties contained in this collection.

Like this

for(x=0;x<=properties.length;x++){
    if(objCheck.hasOwnProperty(properties[x].PropertyName)){
        properties[x].ifDefined();               
    }       
    else{
        properties[x].ifUndefined();
    }

What I want is... I want to bring it to yet another level of dynamicity: Given the propositions that IfDefined and IfUndefined are functions to be called, respectively, if the currently-pointed PropertyName exists, and otherwise, I want to call these functions while providing them, as parameters, the very objCheck.PropertyName's value, so that it can be treated before returning to the user.

I'll give a usage example:

I will feed this function an object I received from an external provider (say, a foreign JSON-returning-WebService) from which I know a few properties that may or may not be defined. For example, this object can be either:

var userData1 = {
    userID : 1
    userName: "JoffreyBaratheon",
    cargo: "King",
    age: 12,
    motherID : 2,
    //fatherID: 5,--Not defined
    Status: Alive
}

or

var userData2 = {
    userID : 
    userName: "Gendry",
    cargo: "Forger Apprentice",
    //age: 35, -- Not Defined
    //motherID: 4,-- Not Defined
    fatherID: 3,
    Status:    Alive
}

My function will receive:

var objEntry=
{
        objCheck: userData1,
        properties: [
            {
                PropertyName: "age",
                ifDefined: function(val){alert("He/she has an age defined, it's "+val+" !");},
                ifUndefined:  function(){alert("He/she does not have an age defined, so we're assuming 20.");},
            },
            {
                PropertyName: "fatherID",
                ifDefined: function(val){alert("He/she has a known father, his ID is "+val+" !");},
                ifUndefined:  function(){alert("Oh, phooey, we don't (blink!blink!) know who his father is!");},
            }

        ]
}

CheckObjectConsistency(objEntry); // Will alert twice, saying that Joffrey's age is 12, and that his father is supposedly unknown.

ifDefined will only actually work if, instead of properties[x].ifDefined();, I somehow provide it with properties[x].ifDefined(PropertyValue);. And here, at last, lies my question.

Being inside the consistency-checking-function, I only know a given property's name if it's provided. Being inside it, I can't simply call it's value, since there is no such function as properties[x].ifUndefined(properties[x].GetValueFromProperty(properties[x].PropertyName)) ,... is there?

I'm sorry. Not being a native english speaker (I'm brazilian), I can't properly express my doubts in a short way, so I prefer to take my time writing a long text, in an (hopefully not wasted) attempt to make it clearer.

If, even so, my doubt is unclear, please let me know.

Upvotes: 0

Views: 76

Answers (1)

Joseph
Joseph

Reputation: 119867

I think you're looking for the bracket notation here. It allows you to provide an arbitrary value as key to access the object. Also, you know its name. You have your properties object right?

objEntry.properties.forEach(function(property){

  // Check if objCheck has a property with name given by PropertyName
  if(!objEntry.objCheck.hasOwnProperty(property.PropertyName)){

    // If it doesn't, call isUndefined
    property.isUndefined();
  } else {

    // If it does, call isDefined and passing it the value
    // Note the bracket notation, allowing us to provide an arbitrary key
    // provided by a variable value to access objCheck which in this case is
    // the value of PropertyName
    property.isDefined(objEntry.objCheck[property.PropertyName]);
  }
});

Oh yeah, forEach is a method of arrays which allows you to loop over them. You can still do the same with regular loops though.

Upvotes: 1

Related Questions