Object has not method error in JavaScript - javascript

I am using following code but it returns following error:
Uncaught TypeError: Object [object HTMLAnchorElement] has no method 'userInput'
Here is the code jsfiddle:
var ClickEvent = function (event) {
this.ev = $('.' + event);
this.ev.on('click', function () { this.userInput(); });
};
ClickEvent.prototype = function () {
return {
userInput: function () {
console.log('user');
},
show: function () {
console.log('show');
}
};
}();
var c = new ClickEvent('event');
I am calling userInput function inside on() callback function but it returns above error.
How can I solve this problem?

The problem is the execution context(this) inside the click callback handler does not point to the ClickEvent instance, it is referencing the dom element that was clicked.
You need to use
this.ev.on('click', $.proxy(function () { this.userInput(); }, this));
Demo: Fiddle
or
var that = this;
this.ev.on('click', function () { that.userInput(); });
Demo: Fiddle

this.userInput() is nested within the callback function, and thus is scoped within it. You could externalize the this instance you need as follow:
var ClickEvent = function (event) {
var $this = this;
$this.ev = $('.' + event);
$this.ev.on('click', function () { $this.userInput(); });
};

the "this" inside your onclick function is referencing "this.ev" which is
"$('.' + event);"
not your object with "userInput" and "show".

Related

Calling a JavaScript function from jQuery returns ReferenceError: method not defined

var MyObj = core.Class.extend({
connect: function() {
$('body').keydown(function (e) {
// want to call disconnect() in here
});
},
disconnect: function() {
}
});
I've tried calling disconnect(), this.disconnect(), but they all return,
ReferenceError: disconnect is not defined
The variable core here is:
core = require('some_module')
You need to store the this context into a variable.
Your code is using this context of this function: $('body').keydown(function (e) {...}
var MyObj = core.Class.extend({
connect: function() {
var $self = this;
$('body').keydown(function(e) {
$self.disconnect();
});
},
disconnect: function() {}
});
The this is not the right this.
Use this :
$('body').keydown((e)=>{
// this.disconnect() in here
})
instead
Lambda functuons keep the context on which they run.
You can also use bind function and also keep a variable which keeps the context and then refer to that variable

Jquery this returns empty object when calling from another function

i have a normal function which works and when i console log this it returns jQuery.fn.init [small.expand, context: small.expand
My function below:
jQuery(document).on('click', 'h3.shipping-name small.expand', function (e) {
var me = jQuery(this);
console.log(me);
var next = me.parent().next().next();
if (next.is(":hidden")) {
me.find('i').removeClass('glyphicon-chevron-down').addClass('glyphicon-chevron-up');
} else {
me.find('i').removeClass('glyphicon-chevron-up').addClass('glyphicon-chevron-down');
}
next.slideToggle();
});
But if i want to get it from another function like this:
var smallExpand = jQuery('h3.shipping-name small.expand');
smallExpand.on("click", function () {
expandDetails();
});
function expandDetails(e) {
alert("oki2");
var me = jQuery(this);
console.log(me);
var next = me.parent().next().next();
console.log(next)
if (next.is(":hidden")) {
me.find('i').removeClass('glyphicon-chevron-down').addClass('glyphicon-chevron-up');
} else {
me.find('i').removeClass('glyphicon-chevron-up').addClass('glyphicon-chevron-down');
}
next.slideToggle();
}
But it returns only empy object like this: jQuery.fn.init {}
What am i doing wrong?
Problem with your implementation is that this doesn't refers to current element it refers to window object thus the code doesn't work
You can use call() to set the this value
smallExpand.on("click", function (event) {
expandDetails.call(this, event);
});
Or, You could just pass the function reference to attach event handler
smallExpand.on("click", expandDetails);
Set the variable first out side your functions, then you can retrieve it for later.
var me;
Then
function first() {
me = $(this);
}
Now you can use the variable in another function
function thisorthat() {
$(‘.class’).val(me);
}
You are calling expandDetails as a static method.
as mentioned by #Satpal, you should just do smallExpand.on("click", expandDetails);.
this exists in the smallExpand.on("click", function() {}); scope, but once you call expandDetails(); it gets lost.

Acces member variables in nested functions

I have a class which uses jQuery functions inside it's internal function.
How can I refer to the member variable inside the jQuery callback function?
See the code below:
var UriParser = function(uri) {
this._uri = uri; // let's say its http://example.com
};
UriParser.prototype.testAction = function() {
$('a').on('click', function(event) {
// I need the above this._uri here,
// i.e. http://example.com
}
}
The problem is this inside the event handler does not refer the UriParser object, it is referring the dom element which was clicked.
One solution is to use a closure variable
UriParser.prototype.testAction = function () {
var self = this;
$('a').on('click', function (event) {
//use self._uri
})
}
another is to use $.proxy() to pass a custom execution context
UriParser.prototype.testAction = function () {
$('a').on('click', $.proxy(function (event) {
//use this._uri
}, this))
}

js code shows error after creating new instance of object

When I create new instance of ClickEvent object it returns following error. Click here for jsfiddle code. Below is my code
var ClickEvent = function (event) {
this.ev = $('.' + event);
this.ev.on('click', this.userInput());
};
ClickEvent.protoype = function () {
return {
userInput: function () {
console.log('user');
},
show: function () {
console.log('show');
}
};
}();
var c = new ClickEvent('event');
c.show();
Why does it show this error and how can I solve it?
Uncaught TypeError: Object [object Object] has no method 'userInput'
There are a couple of issues.
You have a typo in prototype.
this.ev.on('click', this.userInput()); should be this.ev.on('click', this.userInput); - you want to pass a reference to the function so it's executed when the user clicks, you don't want to call it when binding the event handler.
You spelt prototype wrong; your code otherwise executes fine, though you meant to reference the method with this.userInput rather than invoking it right away with this.userInput(), and due to this you get both messages 'show' and 'user' when the page loads.
With those fixes in place, your code functions as I expect you intend: the 'user' only appears when you click on the link.
The error means that no where in the javascript library, a method userInput can be found. Which I can tell is very likely since you have not referenced the userInput variable anywhere before line 3. Also the .on() has two parameters: ("EVENT", "FUNCTION"). In your code, this.userInput is not a function and cannot function as one.
fixed Type, and a little change , this works.
function ClickEvent(event) {
this.ev = $('.' + event);
this.ev.on('click', this.userInput());
};
ClickEvent.prototype = {
userInput: function () {
console.log('user');
},
show: function () {
console.log('show');
}
};
var c = new ClickEvent('event');
c.show();

Variable Scope: this.remove is not a function

this.remove() is not a function. How come?
var vehicle = function () {
return {
init: function () {
jQuery('.vehicle-year-profile .options .delete').bind('click', function (e) {
e.preventDefault();
this.remove();
});
},
remove: function () {
alert('test');
}
}
}();
jQuery().ready(vehicle.init);
Sorry for the confusion. I'm trying to call my own "remove" function. This is simply a class to manage vehicles on my page. This is the beginning of it and it will have a lot more functions than just init/remove.
this is a DOM element. To use jQuery's .remove() method, you need to wrap it in a jQuery object.
$(this).remove();
EDIT: If you were hoping to call the remove() function in the vehicle object, then call:
vehicle.remove();
Also, if you were hoping to shorten your .ready() call, you can do this:
jQuery(vehicle.init);
From the jQuery 1.4 release notes:
The jQuery().ready() technique still works in 1.4 but it has been deprecated. Please use either jQuery(document).ready() or jQuery(function(){}).
Maybe you're looking for something like this?
var vehicle = new function () {
var self = this;
this.init = function () {
jQuery('.vehicle-year-profile .options .delete').bind('click', function (e) {
e.preventDefault();
self.remove();
});
};
this.remove = function () {
alert('test');
};
};
...or like this maybe? It's kind of hard to tell what you're going for...
var vehicle = new function () {
function remove () {
alert('test');
}
this.init = function () {
jQuery('.vehicle-year-profile .options .delete').bind('click', function (e) {
e.preventDefault();
remove.call(this);
});
};
};
Note - we're all somewhat confused because it's not clear which "remove" function you want to call.
The problem is that you're passing in the reference to the "init" function, but when it's called the "this" variable will refer to the window object, not the value of "vehicle". Why? Because in Javascript the "this" value depends only on how a function is called. The fact that two functions are defined in the same object has absolutely nothing to do with it.
Try doing this instead:
jQuery(function() {
vehicle.init();
});
When you call the "init" function that way — by explicitly referencing it as a property of the "vehicle" object — then Javascript will bind "this" to the value of "vehicle".
edit oh wait I just noticed that you're also going to have to revise your "init" function, because that code inside the "click" handler is going to be called by jQuery in such a way as to bind "this" in that context to the affected element. Thus if you want to keep the "vehicle" reference around, you'd do this:
init: function () {
var originalThis = this;
jQuery('.vehicle-year-profile .options .delete').bind('click', function (e) {
e.preventDefault();
originalThis.remove();
});
},
Since you said you're trying to call your own remove function, here's how to do it:
var vehicle = (function () {
return {
init: function () {
var that = this; // step one
jQuery('.vehicle-year-profile .options .delete').bind('click', function (e) {
e.preventDefault();
that.remove();
});
},
remove: function () {
alert('test');
}
}
}()); // step zero - wrap the immediate invocation in parens
jQuery(function () {
vehicle.init(); // step two
);
var vehicle = function () {
return {
init: function () {
var self = this;
jQuery('.vehicle-year-profile .options .delete').bind('click', function (e) {
e.preventDefault();
self.remove();
});
},
remove: function () {
alert('test');
}
}
}();
jQuery().ready(function() {
vehicle.init();
});
When invoking a function as a method "this" refers to the object that is invoking it. In jQuery the function passed is invoked as a method of the html element so "this" becomes the element.
To make sure you are refering to the correct object you'll need to create a reference to the original object.
var vehicle = function () {
var that = {
init: function () {
jQuery('.vehicle-year-profile .options .delete').bind('click', function (e) {
e.preventDefault();
that.remove();
});
},
remove: function () {
alert('test');
}
}
return that;
}();
jQuery().ready(vehicle.init);

Categories