The object does not have a 'apply' method

I create several DOM elements dynamically, for example,

var anchorElement = jQuery('<a />',{text:property.text}); var liElement = jQuery('<li />',{"class":"navlink_"+i,id:"navlink_"+i}); anchorElement.on('click',property.fnctn); liElement.append(anchorElement); parentID.append(liElement); 

Where property is a JSON object. property.text is the text that I want to add to the anchor element. (Works great)

I want to bind a click event handler to this bind element. The function that should be bound to this element is specified in JSON, and we can access it, for example

 property.fnctn 

The next line should bind the event handler to the binding element.

 anchorElement.on('click',property.fnctn); 

This does not work, so I tried converting it to a string, for example,

 anchorElement.on('click',property.fnctn.toString()); 

No success ...

When I click on this link, an error is logged on the console

The object does not have a apply method. What is the reason...???

I can make it work with a little work like

 anchorElement.attr('onclick',property.fnctn+"()"); 

The above instruction works, but I want to know why the .on() API is not working.

Thanks :) Aditya.

+4
source share
1 answer

Update

You said property.actfn is a string, "paySomeoneClick" . It is better not to use strings for event handlers; instead, use functions. If you want the paySomeoneClick function defined in the line to be called, and if this function is global, you can do this:

 anchorElement.on('click',function(event) { return window[property.fnctn](event); }); 

This works because global functions are properties of a global object accessible through a window in browsers, and because of the parenthesized entry described below.

If the function is on the object you are referencing, then:

 anchorElement.on('click',function(event) { return theObject[property.fnctn](event); }); 

This works because in JavaScript you can access the properties of objects in two ways: Dotted notation with the name of the literal property ( foo.bar refers to bar propety on foo ) and bracketing the notation with the name of the string property ( foo["bar"] ). They are equivalent, with the exception of, of course, the notation in brackets; a string can be the result of an expression, including based on the value of a property, such as property.fnctn .

But I would recommend stepping back and reworking a bit so that you don't pass function names in strings. Sometimes this is the correct answer, but in my experience, not often. :-)

Original answer :

(It was assumed that property.fnctn was a function, not a string. But it might be useful to someone ...)

Code

 anchorElement.on('click',property.fnctn); 

attaches the function to the event, but during the function call this will refer to the DOM element, and not to your property object.

To get around this, use jQuery $.proxy :

 anchorElement.on('click',$.proxy(property.fnctn, property)); 

... or ES5 Function#bind :

 anchorElement.on('click',property.fnctn.bind(property)); 

... or closure:

 anchorElement.on('click',function(event) { return property.fnctn(event); }); 

More info (on my blog):

+8
source

All Articles