Trouble with calling a function - javascript

I am trying to call a function inside of a button click event.
$('#btn_save').button().click(function(){
executeStatement();
});
$.fn.executeStatement = function(){
alert("Here!!!");
$.ajax({
url: 'api.php',
data: sqlStatement,
dataType: 'json',
success: function(data)
{
alert("Success!!!");
}
});
}
The problem is that it never gets called because it is undefined according to the debugger: Uncaught ReferenceError: executeStatement is not defined
Can someone give me a hint what is wrong?
Thanks in advance

Unless you are trying to make a jQuery plugin (which I don't think you are?), change your function declaration to:
function executeStatement(){
//code here
}

Just to elaborate on the previous answer, $.fn is kind of like jquery's namespace. Anything that starts with $. is part of jquery. You can actually add functionality to jquery by adding functions to $.fn, but it's probably not what you want.
I found this really confusing at first too, so I thought I'd try to clarity.

Curt's answer is completely correct. But I thought I would add to it.
function executeStatement(){}
this is called a function declaration and will work in this case.
var executeStatement = function(){};
this is called a function expression and will also work in this scenario.

Related

Overload a JS plugin function with a function from inside

I want to call a function which is in my plugin.
I overloaded a function but I want to call another function from it.
$("mySelector").Myplugin({
My_function : function (){
*do some stuf*
function_from_the_plugin();
}
});
An error appears that says "Unknown function". I think it do not search the function in the plugin but outside.
Do you know how I can do?
I already try with "this", a variable corresponding to my plugin object.
If you have an idea please share it with me.
Thank you for reading this post.
Add this.function_from_the_plugin(); in code where Myplugin() is initialized.

How can I wrap code into a module in order to avoid using global variables?

After my previous question, I come up to the following working code that is intended to refresh the DOM periodically by replacing the <div id="test_css_id">...</div> itself. The behavior of both AJAX requests present in the below code is to reload the same code itself.
<div id="test_css_id">
<a id="link_css_id" href="test_url.html">LINK</a>
<script type="text/javascript">
var refreshTimer;
$('#link_css_id').click(function(event) {
event.preventDefault();
$.ajax({
url: $(this).attr('href'),
type: 'PUT',
success: function(data) {
clearInterval(refreshTimer);
$('#test_css_id').replaceWith(data); // Replaces all code including JavaScript with the response data (note: the response data is exactly the same as the code shown here).
}
});
});
$(document).ready(function() {
function refreshFunction(){
$.ajax({
url: 'test_url.html',
type: 'GET',
success: function(data) {
clearInterval(refreshTimer);
$('#test_css_id').replaceWith(data); // Replaces all code including JavaScript with the response data (note: the response data is exactly the same as the code shown here).
}
});
}
refreshTimer = setInterval(refreshFunction, 1000);
});
</script>
</div>
However, as said by the author of the accepted answer, "there are other ways you can do it [..] one way is to wrap all of that code into a module". I am not expert in JavaScript but I would like to understand and learn it a little more.
How can I wrap all of that code into a module in order to avoid using global variables?
Your current code looks like this:
var refreshTimer; //a global variable
$(...).click(...);
To make refreshTimer not global, you need to put it inside a function:
function main(){
var refresherTimer; //this variable is now local to "main"
$(...).click(...);
}
main();
However, doing it this way won't solve the problem completely. While we did get rid of the global variables, we added a new one - the "main" function itself.
The final trick is to turn the "main" function into an anonymous function and invoke it directly. This is the famous "module pattern":
(function(){
var refreshTimer; //local variable to that anonymous function
$(...).click(...);
}()); //and here we call the function to run the code inside it.
The extra parenthesis around everything are important. If you do just function(){}() instead of (function(){}()) then you will get a syntax error.
Here's a nice description of the module pattern in JavaScript.

Calling JavaScript method in a particular scope

Dear All,
I'm using dojo.declare to create classes in JavaScript. In one of the methods, I've an AJAX request. In the load method of that request, I need to execute certain methods.These methods are actually methods of the class that was created using dojo.declare. I tried to execute the method using this. But it gave me method not found error. So I used dojo.hitch(this,testMethod) to invoke it. It worked fine. Now the problem is I've lot of other methods also inside testMethod() which internally calls other methods of my JavaScript class. It is really a pain to have dojo.hitch() everywhere. Is there any work around for this.
dojo.declare("TestClass",null,{
getData:function(url){
dojo.xhrGet({
url:url,
load: function (response){
dojo.hitch(scope of the current object,testMethod(response))
},
error:function(){
}
});
},
testMethod:function(response){
//calls testMethod2. I think I can use dojo.hitch(this,testMethod3) to call it.
//but I wanted to avoid doing it every time.
},
testMethod2:function(){
//calls testMethod3
},
testMethod3:function(){
//can call other methods.
}
});
It seems like that execution scope was lost in this code:
load: function (response){
dojo.hitch(this,testMethod(response))
},
I made small changes in your code. Now it should work properly.
dojo.declare("TestClass",null,{
getData:function(url){
dojo.xhrGet({
url:url,
load: dojo.hitch(this,this.testMethod),
error:function(){
}
});
},
testMethod:function(response){
this.testMethod2();
},
testMethod2:function(){
this.testMethod3();
},
testMethod3:function(){
//can call other methods.
}
});
This is a typical context problem. You are passing an uncontexted function as a property of a configuration hash, which is passed as argument to dojo.xhrGet.
dojo.hitch is exactly the right construct to add a context to a function. Another way is to simply use a closure. Is there any reason why you can't do:
var me = this;
dojo.xhrGet({
url:url,
load: function(response) {
me.testMethod(response);
}
});
Try doing it like this:
dojo.xhrGet({
url:url,
load: dojo.hitch(this, "testMethod"),
error:function(){
}
});
Your way worked as well, but it saves you a few bytes and is just cleaner to use the method name as a string. Hitch will automatically pass the arguments for you.

Using a closure to execute a function in the future?

I'm trying to use a closure (I think that's what it is..), I'd just like to execute a function with a local variable at some point in the future, like this:
function boo() {
var message = 'hello!';
var grok = function() { alert(message); }
foo(grok);
}
function foo(myClosure) {
$.ajax({
timeout: 8000,
success: function(json) {
myClosure();
}
}
}
I could get around this by using global variables and such, but would rather use something like the above because it at least seems a bit cleaner. How (if possible) do you do this?
Thanks
----------- Update --------------------
Sorry I wasn't clear - I was wondering if this is the correct syntax for the closure, I tried it out and it seems ok. Thank you.
Your existing code looks perfectly fine except for that missing paren at the end. ;)
If you're looking to understand the concept of closures more deeply, think of it this way: whenever something in a closured language is defined, it maintains a reference to the local scope in which it was defined.
In the case of your code, the parameter to $.ajax() is a newly-created object ("{ timeout: 8000, etc. }"), which contains a newly-created function (the anonymous "success" function), which contains a reference to a local variable ("myClosure") in the same scope. When the "success" function finally runs, it will use that reference to the local scope to get at "myClosure", even if "foo()" ran a long time ago. The downside to this is that you can end up with a lot of unfreeable data tied up in closures -- the data won't be freed until all references to it have been removed.
In retrospect, I may have confused you more than helped you. Sorry if that's the case. :\
Unless you actually want to make an AJAX call, setTimeout might be more along the lines of what you are looking for:
function foo(myClosure) {
setTimeout(myClosure, 8000); // execute the supplied function after 8 seconds
}
If your question was more along the lines of "Am I creating a closure correctly?", then yes, your function boo is doing the right thing.
Is it what you want?
var boo = (function() {
var message = 'hello!';
return function() {
foo(function() {
alert(message);
});
};
})();
function foo(myClosure) {
$.ajax({
timeout: 8000,
success: function(json) {
myClosure();
}
}
}
or just
function boo() {
$.ajax({
timeout: 8000,
success: function(json) {
alert('hello!');
// do sth with json
// ...
}
}); // <- missed a paren
}
The example is too simple to know what you want btw.

Can I use a static (i.e., predetermined) callback function name when requesting JSONP with jQuery?

The jQuery documentation lists the following example of using $.getJSON to request JSONP:
$.getJSON("http://api.flickr.com/services/feeds/photos_public.gne?tags=cat&tagmode=any&format=json&jsoncallback=?",
function(data) {
$.each(data.items, function(i,item) {
$("<img/>").attr("src", item.media.m).appendTo("#images");
if (i == 3) return false;
});
});
Rather than use this method, which generates a dynamic callback function name because of this parameter:
jsoncallback=?
I want to be able to set that in advance to a hardcoded function name, like this:
jsoncallback=test
This works, in the sense that I run the script and the JSONP that I get back has the JSON object wrapped in a call to test().
However, I can't figure out how to set up the callback function. Shouldn't it be as simple as this?
function test(data) {
console.log(data);
}
$.getJSON("http://api.flickr.com/services/feeds/photos_public.gne?tags=cat&tagmode=any&format=json&jsoncallback=test");
When I try that, I get back the JSONP which is wrapped in test(), but the function test() that I've defined is never called. Am I missing something?
Thanks for any help!
As defined in the documentation for you to use the following method
jQuery.getJSON(...)
you need to specify callback=? when making a JSONP call. I usually only uses this for response types of "json". For response types of "jsonp", you want to use:
jQuery.get(...)
and specify the type as "jsonp". See this documentation on the subject. But that is also bound by the fact of having to have a callback=?.
What I think you are looking for is this:
jQuery.getScript(...)
Which should execute whatever method you have defined in your callback.
Ah, the "Related" sidebar section saved me here. After I submitted this question, I found a similar one already asked:
using a named function as the callback for $.getJSON in jQuery to satisfy Facebook request signing demands
Duncan's answer from Oct. 15 solved this for me:
window.fixed_callback = function(data){
alert(data.title);
};
$(function() {
$.getScript("http://api.flickr.com/services/feeds/photos_public.gne?tags=cats&tagmode=any&format=json&jsoncallback=fixed_callback", function(data) {
alert('done'); } );
});
I guess the key is using $.getScript instead of $.getJSON. One can still specify an anonymous callback function in the parameters of the $.getScript method, which will be executed after the callback function named in the request URL parameters ("fixed_callback" in this case). Hope this helps someone down the road.

Categories