Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery plugin returning "Cannot read property of undefined"

I'm trying to do something i've done numerous times. I can't figure out why this isn't working. No matter how i write the jQuery code, it doesn't work. menuitems[i].action() just does NOT work. Below is Example 1 in which this example, no matter what item is clicked it returns the last item's action (in this example it's the alert('Forward!')). The 2nd returns undefined property. The full error below.

My jQuery plugin is called like this (examples below are what happen with this same call):

$('p').contextMenu([
    {
        name:'Back',
        action:function(){
            alert('Back!');
        },
        icon:'http://cdn.iconfinder.net/data/icons/crystalproject/16x16/actions/agt_back.png'
    },
    {
        name:'Forward',
        action:function(){
            alert('Forward!');
        },
        icon:'http://cdn.iconfinder.net/data/icons/crystalproject/16x16/actions/agt_forward.png'
    }
]);

Example 1:

for (i in menuitems){
    $('<li/>',{
        'html':'<img src="'+menuitems[i].icon+'">'+menuitems[i].name,
        'class':o.itemClass,
        'click':function(){
            menuitems[i].action();
        }
    }).appendTo('.'+o.listClass);
}

This returns an alert with Forward! no matter which item, Back or Forward, is clicked.

Example 2:

var len = menuitems.length;
for (var i = 0; i < len; i++){
    $('<li/>',{
        'html':'<img src="'+menuitems[i].icon+'">'+menuitems[i].name,
        'click':function(){
            menuitems[i].action();
        },
        'class':o.itemClass
    }).appendTo('.'+o.listClass);
}

I get:

Uncaught TypeError: Cannot read property 'action' of undefined

Other random things i tried were detaching the click and reattaching it outside of that appendTo() block, changed action() to newtest() to make sure it wasn't conflicting with any built in keywords. I also tried doing a $('body').append('<li>{blah blah}</li>').find('li').click(function(){/*blah blah*/}); but it still returned the same thing. I'm outta ideas!

like image 268
Oscar Godson Avatar asked Nov 12 '10 05:11

Oscar Godson


People also ask

How do you fix undefined property Cannot be read?

To fix the “cannot read property of undefined” error, use the optional chaining operator on the variable before accessing a property. If the variable is undefined or null , the operator will return undefined immediately and prevent the property access.

Can not read the property of undefined reading get?

The "Cannot read properties of undefined" error occurs when trying to access a property on an undefined value. You often get undefined values when: accessing a property that does not exist on an object. accessing an index that is not present in an array.


1 Answers

The problem is that "i" is incremented, so by the time the click event is executed the value of i equals len. One possible solution is to capture the value of i inside a function:

var len = menuitems.length;
for (var i = 0; i < len; i++){
    (function(i) {
      $('<li/>',{
          'html':'<img src="'+menuitems[i].icon+'">'+menuitems[i].name,
          'click':function(){
              menuitems[i].action();
          },
          'class':o.itemClass
      }).appendTo('.'+o.listClass);
    })(i);
}

In the above sample, the anonymous function creates a new scope which captures the current value of i, so that when the click event is triggered the local variable is used instead of the i from the for loop.

like image 165
nxt Avatar answered Sep 24 '22 06:09

nxt