Prepare a method call for execution - javascript

I want to delay a prepared method call (prepared= all parameters already set) for execution. Example:
I have a textfield with the following listener method:
var storedRequest = null;
function doAjaxRequest() {
//if there is no request at this moment, do the request
//otherwise: store the request and do nothing
}
//will be executed after a request is done
function callbackAjaxRequestComplete() {
//is storedRequest != null --> Execute that request (the last one)
}
So, is there a possiblity to store a PREPARED method call for execution?

var preparedMethod = method.bind(null, param1, param2, param3 /*, ... etc */);
Function.prototype.bind[docs]

You can do something like this:
var preparedOperation = function() {
return actualOperation(param1, param2, param3);
};
Then a call at any time to "preparedOperation" will be a call to your actual function.
The Functional.js library has some interesting support code for that sort of thing.

Related

Make 2 simultaneous ajax calls and call back on completion of both?

I want to make 2 api requests, but calling the second request inside the first's callback function doesn't seem right to me. Is there any way I can just call them both simultaneously and run the callback function only when I got respond from both?
You can use $.when() jquery function.
http://api.jquery.com/jquery.when/
You should use a variable outside the calls that increments on success. In the callback you test if it equals the number of calls, if true then you can call your finish method
Something like this:
var nbSuccess = 0;
var nbCalls = 2;
call_1.success
- nbSuccess++
- if nbSuccess == nbCalls {doFinish}
call_2.success
- nbSuccess++
- if nbSuccess == nbCalls {doFinish}
function doFinish...
Calling the second request inside the first one callback make them Synchronous. The second will only be called when the first has finished.
If you want two send the two call and handle only when the two are done you may (not tested)
Use the same callback for both and use a boolean to ensure both are done.
Something like (pseudo code):
var a1=false; a2=false;
a1.ajax(callback(){a1=true; doAction()}
a2.ajax(callback(){a2=true; doAction()}
function doAction() {
if (a1 && a2) {
...
}
You can do this
var response = 0;
var callback = function () {
if (response === 2){/* code */}
};
// first request
$.get(url).done(function () {
response++;
callback();
});
// second request
$.get(url).done(function () {
response++;
callback();
});
I hope this might helps you. Try this.
$.ajax("yourUrl",function(){
}).done(function(){
$.ajax("yourUrl",function(){
}).done(function(){
// Do your task
});
});

Jquery passing a function to a function

OK, i need some help,
i have a function inside a jquery plugin
var LoadPage = function (page, location, func){
$.ajax({
url: page,
success: function(data){
$(location).html(data); //Insert data into location
func
return true
},
});
}
i want to use it like this
Loadpage(
"api/page.php",
"#div_id",
$("#calander td.clickable").click(function() {
var day = $(this).attr("calendar-day");
console.log("clicked TD" + day);
LoadPage('/api/view_event.php?d='+day, settings.eventContainer);
})
);
or
Loadpage(
"api/page.php",
"#div_id",
function() {
var day = $(this).attr("calendar-day");
console.log("clicked TD" + day);
LoadPage('/api/php/calander/view_event.php?d='+day+'&m='+SelectedMonth+'&y='+SelectedYear, settings.eventContainer);
}
);
and then have it run that in the success: where var func is in it but unsure how to get this to work. please help internet.
There are three separate issues in your code:
1) If you want to execute the callback func in your success handler, then you need to add parens () after it as in func() as that is javascript's method of signifying that you want to execute a function.
var LoadPage = function (page, location, func){
$.ajax({
url: page,
success: function(data){
$(location).html(data); //Insert data into location
// add parens here after func
func();
return true
},
});
}
If you want the func argument to be optional, you can test for it before executing it like this:
var LoadPage = function (page, location, func){
$.ajax({
url: page,
success: function(data){
$(location).html(data); //Insert data into location
// add parens here after func to actually execute it
if (func) func();
return true
},
});
}
2) Then, you need to change how you call LoadPage() to pass it an actual function reference like this:
Loadpage(
"api/page.php",
"#div_id",
function() {
$("#calander td.clickable").click(function() {
var day = $(this).attr("calendar-day");
console.log("clicked TD" + day);
LoadPage('/api/view_event.php?d='+day, settings.eventContainer);
})
})
);
What you were passing it was the result of executing the .click function which is a jQuery object, not a function. Instead, you can wrap that in an anonymous function so you're passing a reference to that function. This is the opposite of the func(). You don't want parens after what you pass because you want to pass a reference to a function, not the result of executing the function now.
So, to summarize these two issues:
The statement:
func
is just a reference to a function. It doesn't actually execute the function. It is useful when you want to pass a reference to a function which will then call it LATER.
The statement:
func()
executes the function immediately. If you pass func() as an argument, then it will execute immediately (parens always mean to execute it now) and then pass the return value of that function (which is not what you want here).
3) You may also want to understand that the return true statement in your success handler does NOTHING. Because the ajax function is asychronous, your LoadPage() function just starts the ajax function and then returns immediately. Sometime later, the internals of the ajax engine calls your success handler. That return statement returns back into the interior of that ajax engine. It does NOT return from your LoadPage() function since that has already long since completed and returned nothing.
4) Possible fourth issue. Every time you call LoadPage(), you are going to add a new click handler to whatever objects this selector matches: "#calander td.clickable". If some of those objects existed previously, you will end up with multiple click handlers. In that case, you would either want to use delegated event handling so you could just install the click handler once ahead of time or you would need to remove the exist click handlers before installing the new ones or you would need to isolate only the newly added objects and only call it on them. If all "#calander td.clickable" are replaced by the previous code, then this would not be a problem.
Try this:
var LoadPage = function (page, location, func){
$.ajax({
url: page,
success: function(data){
$(location).html(data); //Insert data into location
func && func(); // this will execute func if it is passed as parameter
return true;
}
});
}
And use it in the second way.

Javascript callback function with parameters [duplicate]

This question already has answers here:
Pass an extra argument to a callback function
(5 answers)
Closed 6 years ago.
This question looks like a duplicate, as the title is nearly replicated. But, my issue seems simpler and I can't find the answer to it.
I have a Javascript function that executes another callback function, it works like this:
<script type='text/javascript'>
firstfunction(callbackfunction);
</script>
where callback function is defined as:
callbackfunction(response) {
if (response=='loggedin'){
// ... do stuff
}}
but I want it to be something like this:
callbackfunction(response, param) {
if (response=='loggedin'){
// ... do stuff with param
}}
My question is, does it work to pass the parameter like this:
<script type='text/javascript'>
firstfunction(callbackfunction(param));
</script>
or am I doing it wrong?
In direct answer to your question, this does not work:
firstfunction(callbackfunction(param));
That will execute callbackfunction immediately and pass the return value from executing it as the argument to firstfunction which is unlikely what you want.
It is unclear from your question whether you should just change firstfunction() to pass two parameters to callbackfunction() when it calls the callback or whether you should make an anonymous function that calls the callback function with arguments.
These two options would look like this:
function firstfunction(callback) {
// code here
callback(arg1, arg2);
}
firstfunction(callbackfunction);
or
function firstfunction(callback) {
// code here
callback();
}
firstfunction(function() {
callbackfunction(xxx, yyy);
});
Use an anonymous function:
function foo( callback ) {
callback();
}
function baz( param ) {
console.log( param );
}
foo( function(){ baz('param') });
Adding parameters when calling a function.
https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function/apply
xdaz already answered the simple version.
Here is an example with variable amount of parameters.
function someObject(){
this.callbacks=new Array();
this.addCallback=function(cb){
this.callbacks[this.callbacks.length]=cb
}
this.callCallbacks=function(){
//var arr=arguments; this does not seem to work
//arr[arr.length]="param2";
var arr = new Array();
for(i in arguments){
arr[i]=arguments[i];
}
arr[arr.length]="another param";
i=0;
for(i in this.callbacks){
this.callbacks[i].apply(null,arr);
//this.callbacks[i].apply(this,arr);
//this is a ref to currrent object
}
}
this.callCallbacksSimple=function(arg){
for(i in this.callbacks){
this.callbacks[i](arg,"simple parameter");
}
}
}
function callbackFunction(){
for(i in arguments){
console.log("Received argument: " + arguments[i]);
}
}
var ObjectInstance=new someObject();
ObjectInstance.addCallback(callbackFunction);
ObjectInstance.callCallbacks("call callbacks");
ObjectInstance.callCallbacksSimple("call callbacks");
function is key word, you can't use it as function name.
Let say your function name is foo, then you could do like below:
var param = 'what ever';
foo(function(response) {
callbackfunction(response, param);
});
I think this is what you're looking for.
Lets say you're using jQuery ajax to do something, and you're passing it named callbacks. Here we have an onError callback that you might use to log or handle errors in your application. It conforms to the jQuery Ajax error callback signature, except for an extra parameter that you might have wanted to add at the back
function onError(jqXHR, textStatus, errorThrown, yourOwnVariableThing) {
console.error('Something went wrong with ' + yourOwnVariableThing);
}
this is where your function would be called - but you want an extra parameter
$.ajax("/api/getSomeData/")
.done(onDone)
.fail(onError)
.always(onComplete);
So this is what you can do to add the extra parameter
$.ajax("/api/getSomeData/")
.done(onDone)
.fail(onError.bind(this, arguments[0], arguments[1], arguments[2], 'Moo Moo');
.always(onComplete);
arguments is an array in JavaScript that contains all arguments passed to a function, and so you're just passing those arguments along to the callback.
Arguments
Bind

How to return an array made in a child jQuery function from the parent function in Javascript?

I'm using a jQuery json function inside another function, how can I return an array made in the jQuery function as the return value of my parent function?
this is the basic setup
function getFlickrSet(flickr_photoset_id){
var images = [];
images = $.getJSON(url, function(data){ return data; // I HAVE THE DATA HERE };
return images // I HAVE NO DATA HERE
}
var myImages = getFlickrSet(23409823423423);
alert(myImages); // this gives me nothing
I have set up an example on jsfiddle right here, if you could tell me where my code is wrong, I would greatly appreciate it.
Thank you!
You can't. Instead, pass in a function:
function getFlickrSet(flickr_photoset_id, when_ready){
var images = [];
$.getJSON(url, function(data){
// prepare images
when_ready( images );
});
}
getFlickrSet(nnnn, function(images) {
alert(images);
});
Why can't you do that? Because the "$.getJSON()" call is asynchronous. By the time that the callback function is called (where you wrote, "I HAVE THE DATA HERE"), the outer function has returned already. You can't make the browser wait for that call to complete, so instead you design the API such that code can be passed in and run later when the result is available.
Well, Ajax is asynchronous (that's what the 'A' stands for), so you must do this in an asynchronous way, which boils down to callbacks. What you need to do is pass a callback function to your outer function that you want to be called ("called back," if you will) when the Ajax request completes. You could just give it 'alert' like this:
function getFlickrSet(flickr_photoset_id) {
images = $.getJSON(url, alert); // <-- just the name of the function, no ()
}
var myImages = getFlickrSet(23409823423423);
// => An alert pops up with the data!
...but more likely you'd write something like this:
function doSomethingWithData(data) { // we'll use this later
alert(data); // or whatever you want
}
function getFlickrSet(flickr_photoset_id, callback) {
// new parameter here for a function ------^
// to be given here -------v
images = $.getJSON(url, callback);
return images // I HAVE NO DATA HERE
}
var myImages = getFlickrSet(23409823423423, doSomethingWithData);
// => Your function `doSomethingWithData` will be called the data as a parameter
// when the $.getJSON request returns.

calling a javascript function (in original function) from called function?

Is there anyway to calling a function from another function .. little hard to explain. heres in example. One function loads html page and when ready it calls the original function.
I think i need to pass in a reference but unsure how to do this... if i set it to "this" - it doesn't seem to work
ANy ideas?
order.prototype.printMe = function(){
order_resume.loadthis("myTestPage.html", "showData");
}
order.prototype.testme= function(){
alert("i have been called");
}
//Then when in "loadthis" need to call
orderRsume.prototype.loadthis= function(){
// DO SOME STUFF AND WHEN LOADS IT ARRIVES IN OnReady
}
order.prototype.OnReady= function(){
/// NEED TO CALL ORIGINAL "testme" in other function
}
It's not clear for me what you really want to do. In JS functions are first-class objects. So, you can pass function as a parameter to another function:
Cook("lobster",
"water",
function(x) { alert("pot " + x); });
order.somefunc = function(){
// do stuff
}
order.anotherone = function(func){
// do stuff and call function func
func();
}
order.anotherone(order.somefunc);
And if you need to refer to unnamed function from it's body, following syntax should work:
order.recursivefunc = function f(){
// you can use f only in this scope, afaik
f();
};
I slightly changed the signature of your loadthis function aloowing it to be passed the order to actually load.
I also assumed that your doSomeStuff function accepts a callback function. I assumed that it may be an AJAX call so this would be trivial to call a callback function at the end of the AJAX call. Comment this answer if you need more info on how to fire this callback function from your AJAX call.
order.prototype.printMe = function(){
order_resume.load(this, "myTestPage.html", "showData");
}
order.prototype.testme= function(){
alert("i have been called");
}
//Then when in "loadthis" need to call
orderRsume.prototype.load = function(order, page, action){
// DO SOME STUFF AND WHEN LOADS IT ARRIVES IN OnReady
doSomeStuff(page, action, function()
{
order.OnReady();
});
}
order.prototype.OnReady= function(){
/// NEED TO CALL ORIGINAL "testme" in other function
this.testme();
}

Categories