14

Is there a way for this line to always work and not throw TypeError: Cannot read property 'Whatever' of undefined

var MyArray = [];
MyArray[StringVariableName][StringVariableName2].push("whatever");
Sachin Jain
  • 21,353
  • 33
  • 103
  • 168
Nadav Miller
  • 491
  • 2
  • 5
  • 15

5 Answers5

19

Try this:

var MyArray = [];
MyArray[StringVariableName] = MyArray[StringVariableName] || [];
MyArray[StringVariableName][StringVariableName2] = MyArray[StringVariableName][StringVariableName2] || [];
MyArray[StringVariableName][StringVariableName2].push("whatever");
ppoliani
  • 4,792
  • 3
  • 34
  • 62
  • Works amazing, can you explain what that assignment means? – Nadav Miller Feb 18 '14 at 16:30
  • @NadavMiller It simply is a logical OR. If first part is true, second part is not executed and first part is assigned to the variable. – Sachin Jain Feb 18 '14 at 16:31
  • It is the logical OR operator and it simply says: If the left operand is a truthy value then return it otherwise return the right operand. – ppoliani Feb 18 '14 at 16:33
3

You could even, through the power of expressions, do this with a one-liner.

(MyArray[StringVariableName][StringVariableName2] || (MyArray[StringVariableName][StringVariableName2] = [])).push("whatever");
Jack
  • 1,901
  • 1
  • 19
  • 32
0

I think instead of using array in the first place, use object if your keys are not integers. In Javascript Arrays are also object So it is not wrong to do this

var a = [];
a['key'] = 'something';

console.log(a); //Gives []

I think it is conceptually wrong So instead of using Array to hold such pair of data you should use objects. See this:

var myObject = myObject || {};
myObject[str1] = myObject[str1] || {};
myObject[str1][str2] = myObject[str][str2] || [];

// Now myObject[str1][str2] is an array. Do your original operation

myObject[str1][str2].push("whatever");
Sachin Jain
  • 21,353
  • 33
  • 103
  • 168
0

You could use the literal syntax to set things up like you'd have them:

var myObj = {
    StringVariableName: {
        StringVariableName2: []
    }
};

myObj.StringVariableName.StringVariableName2.push("whatever");
Laoujin
  • 9,962
  • 7
  • 42
  • 69
  • You are doing it wrong way because StringVariableName looks like actually a variable name. You are making them as constant keys in the object. – Sachin Jain Feb 18 '14 at 16:30
0

To check without getting an error:

this snippet allows you to check if a chained object exists.

var x;
try{x=MyArray[name1][name2][name3][name4]}catch(e){}
!x||(x.push('whatever'));

from

https://stackoverflow.com/a/21353032/2450730

Shorthand creation of object chains in Javascript

this function allows you to create chained objects with a simple string.

function def(a,b,c,d){
 c=b.split('.');
 d=c.shift();//add *1 for arrays
 a[d]||(a[d]={});//[] for arrays
 !(c.length>0)||def(a[d],c.join('.'));
}

usage

var MyArray={};//[]
def(MyArray,'name1.name2.name3.name4');//name1+'.'+name2....

from

https://stackoverflow.com/a/21384869/2450730

both work also for arrays with a simple change.replace {} with []

if you have any questions just ask.

Community
  • 1
  • 1
cocco
  • 16,442
  • 7
  • 62
  • 77