Rectangle 27 25

Arrays in JavaScript have quirks of their own that you may not be expecting if you come from other languages. Two important ones for your use case are:

  • You cannot directly declare multidimension arrays in JavaScript.
  • There's little efficiency benefit (and no added safety) when you set the size of the array at creation.

Unlike other languages, JavaScript won't allocate a block of memory for the full array. (It doesn't know what kind of objects you're going to be putting in each cell, and therefore how much total memory it will need.) Instead, all the size argument to Array() does for you is set the array's length property.

For the general, 2d array case, I'd suggest:

  • Create the "top" array, e.g.: var i // the first-order index in a , j // the second order index in a , a = []

Initialize array elements as needed. This is called lazy initialization, and, in this case, it simply involves testing that a[i] exists before we try to assign something to a[i][j], e.g.:

if (!a[i]) a[i] = []

In English the above statement reads: "If the i-th element of a is 'falsy', assign an empty array to the i-th element."

Finally, assign the actual value to the multideminsional array:

a[i][j] = 'whatever'

For your case, you know the values ahead of time, so you can initialize each element in advance. (If you're not overriding most of the elements, however, a lazy implementation may be better; see below.)

var x, x_length = 100
  , y, y_length = 100
  , map = []

// Don't be lazy
for (x = 0; x < x_length; x++) {
  map[x] = []
  for (y = 0; y < y_length; y++) {
    map[x][y] = 'grass.gif|ongrass.gif|collision.gif|above.gif'
  }
}

As some others have said, an array with 100 elements has indexes numbered from zero to ninety-nine, so a less-than comparison is most appropriate here.

For reference, here's an implementation that uses lazy initialization. I've gone with a function interface instead of directly accessing the array; it's longer and more complex, but also more complete.

The initialization pattern I've used here is called an immediately invoked function expression. If you haven't seen it before, it's one of the more useful JavaScript patterns and well worth taking some time to understand.

var map = (function (x_length, y_length, v_default, undefined) {
  // Unless v_default is overwritten, use ...
  v_default = v_default || 'grass.gif|ongrass.gif|collision.gif|above.gif'

  // Private backing array; will contain only values for a[x][y] 
  // that were explicitly set.
  var a = []

  // Private helper function. 
  // - Returns `true` if `x` is between `0` and `x_length - 1`
  //   and `y` is between `0` and `y_length - 1`.
  // - Returns `false` otherwise.
  function valid (x, y) {
    return (x >= 0 
      &&    x <  x_length
      &&    y >= 0
      &&    y <  y_length)
  }

  // Private helper function.
  // - Returns `true` if a[x][y] has been set().
  // - Returns `false` otherwise.
  function exists (x, y) {
    return !!a[x] && !!a[x][y]
  }

  // Private getter
  // - Returns the value of a[x][y] if it has been set().
  // - Returns `undefined` if the point (x,y) is invalid.
  // - Returns `v_default` otherwise.
  function get (x, y) {
    if (!valid(x, y))      return undefined
    else if (exists(x, y)) return a[x][y]
    else                   return v_default
  }

  // Private setter
  // - Returns the value set on success.
  // - Returns `undefined` on failure
  function set (x, y, v) {
    if (valid(x, y)) {
      // We're being lazy
      if (!a[x]) a[x] = []
      a[x][y] = v
      return a[x][y]
    }
    return undefined
  }

  // Return an interface function. 
  // - Pass the function three arguments, (x, y, v), to set a[x][y] = v
  // - Pass the function two arguments, (x, y), to get a[x][y]
  return function (x, y, v) {
    if (arguments.length > 2) {
       return set(x, y, v)
    } else {
       return get(x, y)
    }
  }
})(100, 100)

When I ran the above in node, the following tests printed sensible values:

// Invalid invocations
console.log('map()                : %s', map())
console.log('map(  0)             : %s', map(0))
console.log('map( -1,   0)        : %s', map(-1,0))
console.log('map(  0,  -1)        : %s', map(0, -1))
console.log('map( -1,  -1)        : %s', map(-1, -1))

// Valid invocations
console.log('map(  0,   0)        : %s', map(0, 0))
console.log('map( 99,  99)        : %s', map(99, 99))
console.log('map(  1,   1)        : %s', map(1,1))
console.log('map(  1,   1, "foo") : %s', map(1,1, 'foo'))
console.log('map(  1,   1)        : %s', map(1,1))

javascript - Uncaught TypeError: Cannot set property '0' of undefined ...

javascript
Rectangle 27 24

Arrays in JavaScript have quirks of their own that you may not be expecting if you come from other languages. Two important ones for your use case are:

  • You cannot directly declare multidimension arrays in JavaScript.
  • There's little efficiency benefit (and no added safety) when you set the size of the array at creation.

Unlike other languages, JavaScript won't allocate a block of memory for the full array. (It doesn't know what kind of objects you're going to be putting in each cell, and therefore how much total memory it will need.) Instead, all the size argument to Array() does for you is set the array's length property.

For the general, 2d array case, I'd suggest:

  • Create the "top" array, e.g.: var i // the first-order index in a , j // the second order index in a , a = []

Initialize array elements as needed. This is called lazy initialization, and, in this case, it simply involves testing that a[i] exists before we try to assign something to a[i][j], e.g.:

if (!a[i]) a[i] = []

In English the above statement reads: "If the i-th element of a is 'falsy', assign an empty array to the i-th element."

Finally, assign the actual value to the multideminsional array:

a[i][j] = 'whatever'

For your case, you know the values ahead of time, so you can initialize each element in advance. (If you're not overriding most of the elements, however, a lazy implementation may be better; see below.)

var x, x_length = 100
  , y, y_length = 100
  , map = []

// Don't be lazy
for (x = 0; x < x_length; x++) {
  map[x] = []
  for (y = 0; y < y_length; y++) {
    map[x][y] = 'grass.gif|ongrass.gif|collision.gif|above.gif'
  }
}

As some others have said, an array with 100 elements has indexes numbered from zero to ninety-nine, so a less-than comparison is most appropriate here.

For reference, here's an implementation that uses lazy initialization. I've gone with a function interface instead of directly accessing the array; it's longer and more complex, but also more complete.

The initialization pattern I've used here is called an immediately invoked function expression. If you haven't seen it before, it's one of the more useful JavaScript patterns and well worth taking some time to understand.

var map = (function (x_length, y_length, v_default, undefined) {
  // Unless v_default is overwritten, use ...
  v_default = v_default || 'grass.gif|ongrass.gif|collision.gif|above.gif'

  // Private backing array; will contain only values for a[x][y] 
  // that were explicitly set.
  var a = []

  // Private helper function. 
  // - Returns `true` if `x` is between `0` and `x_length - 1`
  //   and `y` is between `0` and `y_length - 1`.
  // - Returns `false` otherwise.
  function valid (x, y) {
    return (x >= 0 
      &&    x <  x_length
      &&    y >= 0
      &&    y <  y_length)
  }

  // Private helper function.
  // - Returns `true` if a[x][y] has been set().
  // - Returns `false` otherwise.
  function exists (x, y) {
    return !!a[x] && !!a[x][y]
  }

  // Private getter
  // - Returns the value of a[x][y] if it has been set().
  // - Returns `undefined` if the point (x,y) is invalid.
  // - Returns `v_default` otherwise.
  function get (x, y) {
    if (!valid(x, y))      return undefined
    else if (exists(x, y)) return a[x][y]
    else                   return v_default
  }

  // Private setter
  // - Returns the value set on success.
  // - Returns `undefined` on failure
  function set (x, y, v) {
    if (valid(x, y)) {
      // We're being lazy
      if (!a[x]) a[x] = []
      a[x][y] = v
      return a[x][y]
    }
    return undefined
  }

  // Return an interface function. 
  // - Pass the function three arguments, (x, y, v), to set a[x][y] = v
  // - Pass the function two arguments, (x, y), to get a[x][y]
  return function (x, y, v) {
    if (arguments.length > 2) {
       return set(x, y, v)
    } else {
       return get(x, y)
    }
  }
})(100, 100)

When I ran the above in node, the following tests printed sensible values:

// Invalid invocations
console.log('map()                : %s', map())
console.log('map(  0)             : %s', map(0))
console.log('map( -1,   0)        : %s', map(-1,0))
console.log('map(  0,  -1)        : %s', map(0, -1))
console.log('map( -1,  -1)        : %s', map(-1, -1))

// Valid invocations
console.log('map(  0,   0)        : %s', map(0, 0))
console.log('map( 99,  99)        : %s', map(99, 99))
console.log('map(  1,   1)        : %s', map(1,1))
console.log('map(  1,   1, "foo") : %s', map(1,1, 'foo'))
console.log('map(  1,   1)        : %s', map(1,1))

javascript - Uncaught TypeError: Cannot set property '0' of undefined ...

javascript
Rectangle 27 66

Another reason this error can occur is if you load the unobtrusive script before jquery.validate.

<script src="/scripts/jquery.validate.unobtrusive.min.js" type="text/javascript"></script>
<script src="/scripts/jquery.validate.min.js" type="text/javascript"></script>

will give the "Cannot set property 'unobtrusive' of undefined" error.

Sign up for our newsletter and get our top new questions delivered to your inbox (see an example).

jquery - Uncaught TypeError: Cannot set property 'unobtrusive' of unde...

jquery jquery-ui microsoft-cdn
Rectangle 27 6

You want literal notation:

var years= new Array(113);
for(i=0;i<113;i++){
    years[i] = {text: String(i + 1900), value: i + 1900};
}

The reason you were getting the error is that you never assigned anything to years[i], but you were trying to use it in the expression years[i]["text"] (which means "get the property with the name from i from the years object, and then get the property "text" from that).

Note that there's no benefit in attempting to pre-allocate room for a standard array in JavaScript, because JavaScript standard arrays aren't really arrays at all. So perhaps:

var years= [];
for(i=0;i<113;i++){
    years[i] = {text: String(i + 1900), value: i + 1900};
}

Similarly, you could just loop from 1900 (inclusive) to 2013 (exclusive) rather than doing all of that addition in the loop:

var years= [];
for(i=1900;i<2013;i++){
    years.push({text: String(i), value: i});
}

Sign up for our newsletter and get our top new questions delivered to your inbox (see an example).

javascript - Uncaught TypeError: Cannot set property 'text' of undefin...

javascript jquery
Rectangle 27 3

jQuery('.joke').click(function(){
    $(this).css('height','400px');
});

javascript - Uncaught TypeError: Cannot set property 'height' of undef...

javascript jquery
Rectangle 27 3

Since getElementsByClassName returns array of elements, You need to specify the index too,

document.getElementsByClassName("img-icon-invite")[0].style.background="url('<?php echo Yii::app()->theme->baseUrl;?>/style/home/images/firstProPopup-sprite-new-white.png')";

Or with Jquery you can do,

$(".img-icon-invite").css('background-image', 'url(' + imageUrl + ')');

javascript - Uncaught TypeError: Cannot set property 'background' of u...

javascript jquery css3
Rectangle 27 2

for (i=0; i<=2; i++)
for (i=0; i<=x_world_map_tiles ; i++)
for (i=0; i < x_world_map_tiles ; i++)
'for (i=0; i<=x_world_map_tiles; i++)//just a test'

Ok, agreed, it would work, but that is actually incorrect as well ;)

@FelixKling Why is it incorrect? Because the OP defines 100, but creates 101 instances?

javascript - Uncaught TypeError: Cannot set property '0' of undefined ...

javascript
Rectangle 27 2

var x_world_map_tiles = 100;
var y_world_map_tiles = 100;
var world_map_array = new Array(x_world_map_tiles);
for (i=0; i<=2; i++)//create a two dimensional array 
{
    world_map_array[i]=new Array(y_world_map_tiles);
}
for (i=0; i<x_world_map_tiles; i++)
{
    for (z=0; z<y_world_map_tiles; z++)
    {
        world_map_array[i][z]="grass.gif|ongrass.gif|collision.gif|above.gif";
    }
}

As your array has a length of 100, you must go from 0 to 99 (<100) and not to 100 (<=)

javascript - Uncaught TypeError: Cannot set property '0' of undefined ...

javascript
Rectangle 27 2

for (i=0; i<=2; i++)
for (i=0; i<=x_world_map_tiles ; i++)
for (i=0; i < x_world_map_tiles ; i++)
'for (i=0; i<=x_world_map_tiles; i++)//just a test'

Ok, agreed, it would work, but that is actually incorrect as well ;)

@FelixKling Why is it incorrect? Because the OP defines 100, but creates 101 instances?

javascript - Uncaught TypeError: Cannot set property '0' of undefined ...

javascript
Rectangle 27 2

var x_world_map_tiles = 100;
var y_world_map_tiles = 100;
var world_map_array = new Array(x_world_map_tiles);
for (i=0; i<=2; i++)//create a two dimensional array 
{
    world_map_array[i]=new Array(y_world_map_tiles);
}
for (i=0; i<x_world_map_tiles; i++)
{
    for (z=0; z<y_world_map_tiles; z++)
    {
        world_map_array[i][z]="grass.gif|ongrass.gif|collision.gif|above.gif";
    }
}

As your array has a length of 100, you must go from 0 to 99 (<100) and not to 100 (<=)

javascript - Uncaught TypeError: Cannot set property '0' of undefined ...

javascript
Rectangle 27 2

assign the {} ,before inserting value

myarray[var_id]={};
myarray[var_id]['product_id'] = product_id; //error points here
myarray[var_id]['quantity'] = quantity;
myarray[var_id]['variation_id'] = var_id;

javascript - Uncaught TypeError: Cannot set property 'product_id' of u...

javascript jquery
Rectangle 27 2

You need to initialise myarray[var_id] by creating an object in there before setting its properties:

Note that you can make this code more succinct, like this:

if (var_id) {  
    myarray[var_id] = {
        'product_id': product_id,
        'quantity': quantity,
        'variation_id': var_id
    }; 
} 
else {
    myarray[product_id] = {
        'quantity': quantity
    };
}

when i check the header response in google chrome product_array[]: is shown 50 times before it actually shows the array values. It only loops twice, why does it show several blank product_array[]: ?

That would depend on the number of iterations in your parent.each(fn) loop

the number of iterations is only two?

javascript - Uncaught TypeError: Cannot set property 'product_id' of u...

javascript jquery
Rectangle 27 1

  • You need to check if the element exists (difficult to tell without your markup).
var element = document.getElementsByTagName("td")[i];
element && element.onclick = function(){
    switchNote( num, note )
};
  • Value of an onclick handler cannot be a string, it has to be a function.

Testing if the element exists inside the loop seems a bit pointless, because as soon as i reaches a high enough value that the corresponding element doesn't exist none of the higher indexed elements will exist either. So better to just exit the loop or fix the loop condition.

@nnnnnn true, but without markup or details of OP's specific context, it is difficult to tell if the loop is indeed a problem.

@TendelT. are you getting the same error?

javascript - Uncaught TypeError: cannot set property 'onClick' of unde...

javascript
Rectangle 27 1

jQuery('.joke').click(function(){
    $(this).css("height", "400px");
});

In your code joke is the jQuery object, and it doesn't have the style property. And you should use this beacuse otherwise you are refering to all the elements that has the "joke" class.

javascript - Uncaught TypeError: Cannot set property 'height' of undef...

javascript jquery
Rectangle 27 1

I think the problem is that ('#product_right').followTo(250); is not triggered within your website. Try to add the following code to your site:

$( document ).ready(function() {
    ('#product_right').followTo(250);
});

That could also explain why it works within JSFiddle and not on your website. You might try that.

I'm having some confict with JQuery because now I get: Uncaught TypeError: $(...).ready is not a function. Thanks @Rotan075

Yep! that is definitely a jQuery source problem. That should also explain why the value is undefined. I would also (for testing purposes) check if the value is passed correctly to the function by adding a console.log like: console.log(pos)

Besides that I also see that you load multiple jquery version files in your website. Try to avoid that. Use only 1 jQuery version to prevent conflicting code ;) @superTramp

javascript - Uncaught TypeError: Cannot set property 'followTo' of und...

javascript jquery
Rectangle 27 1

Use this instead of jQuery('.joke'), this refers to dom object

jQuery('.joke').click(function(){
    var joke = this;
    joke.style.height = '400px';
});

javascript - Uncaught TypeError: Cannot set property 'height' of undef...

javascript jquery
Rectangle 27 1

years[i] is not set to anything (years[i] == undefined), so you can't access text on it. Try it with the following:

var years = new Array(113);
for(i=0; i < 113; i++) {
    years[i] = {"text": i+1900, "value": i+1900};
}
var years = new Array();
for(i=0; i < 113; i++) {
    years.push({"text": i+1900, "value": i+1900});
}

javascript - Uncaught TypeError: Cannot set property 'text' of undefin...

javascript jquery
Rectangle 27 1

Your json is an object. You'll have to convert it to an array for the tree to work. You can either change your php to return a proper array or use javascript to convert it to an array as shown below.

var data = {
  "2": {
    "id": "12",
    "text": "Certified copy",
    "Description": "",
    "root": "0"
  },
  "3": {
    "id": "13",
    "text": "Charter",
    "Description": "",
    "root": "0"
  },
  "4": {
    "id": "14",
    "text": "Codicil (will)",
    "Description": "",
    "root": "0"
  },
  "5": {
    "id": "15",
    "text": "Cohabitation agreement",
    "Description": "",
    "root": "0"
  },
  "6": {
    "id": "16",
    "text": "Collateral assurance",
    "Description": "",
    "root": "0"
  },
  "7": {
    "id": "17",
    "text": "Commercial invoice",
    "Description": "",
    "root": "0"
  },
  "8": {
    "id": "18",
    "text": "Complaint",
    "Description": "",
    "root": "0"
  },
  "9": {
    "id": "19",
    "text": "Conservation easement",
    "Description": "",
    "root": "0"
  },
  "10": {
    "id": "20",
    "text": "Consignee",
    "Description": "",
    "root": "0"
  },
  "11": {
    "id": "21",
    "text": "Consumer complaint",
    "Description": "",
    "root": "0"
  },
  "12": {
    "id": "22",
    "text": "Contract",
    "Description": "",
    "root": "0"
  },
  "13": {
    "id": "23",
    "text": "Contractual term",
    "Description": "",
    "root": "0"
  },
  "14": {
    "id": "24",
    "text": "Contractual terms in English law",
    "Description": "",
    "root": "0"
  },
  "15": {
    "id": "25",
    "text": "Florence Annie Conybeare",
    "Description": "",
    "root": "0"
  },
  "16": {
    "id": "26",
    "text": "Copyright transfer agreement",
    "Description": "",
    "root": "0"
  },
  "17": {
    "id": "27",
    "text": "Countersign (legal)",
    "Description": "",
    "root": "0"
  },
  "18": {
    "id": "28",
    "text": "County Court judgment",
    "Description": "",
    "root": "0"
  },
  "19": {
    "id": "29",
    "text": "Credit Support Annex",
    "Description": "",
    "root": "0"
  },
  "20": {
    "id": "30",
    "text": "Customs declaration",
    "Description": "",
    "root": "0"
  },
  "21": {
    "id": "31",
    "text": "Bills",
    "Description": "",
    "root": "0",
    "nodes": [{
      "id": "4",
      "text": "Bill of costs",
      "Description": "This type gather all documents related to costs",
      "root": "31"
    }, {
      "id": "5",
      "text": "Bill of sale",
      "Description": "",
      "root": "31"
    }]
  }
};

var dataArray = [];
for (var key in data) {
    if (data.hasOwnProperty(key)) {
        dataArray.push(data[key]);
    }
};

$('#tree').treeview({data: dataArray});
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://rawgit.com/jonmiles/bootstrap-treeview/master/dist/bootstrap-treeview.min.js"></script>
<div id="tree"></div>

javascript - Uncaught TypeError: Cannot set property 'nodeId' of undef...

javascript jquery json bootstrap-treeview
Rectangle 27 20

Assuming you are importing Component as a React.Component correctly, try removing the parenthesis after Component.

class Portfolio extends Component () {
Component
React.Component

javascript - React-router: TypeError: Cannot set property 'props' of u...

javascript meteor reactjs react-router
Rectangle 27 94

d[a]
undefined

If you add d[a] = {} right after d = {} things should work as expected.

d[a] = {
    greetings: b,
    data: c
};

Or you could set all the properties of d in an anonymous function instance:

d = new function () {
    this[a] = {
        greetings: b,
        data: c
    };
};

If you're in an environment that supports ES2015 features, you can use computed property names:

d = {
  [a]: {
    greetings: b,
    data: c
  }
};

This does work. the pattern should be: d = { [a]: { greetings: b, data: c } }

@robertjewell, good point, I've updated to include the note about ES2015 notation.

JavaScript - cannot set property of undefined - Stack Overflow

javascript