A few questions on callbacks, using some example code..
function uploadPhoto(params){
var win = function(response){
console.log("Success!");
console.log("Response: ", response);
}
var fail = function(error){
console.log("Failed.");
console.log("Error: ", error);
}
var options = {params: params};
var ft = new FileTransfer();
ft.upload(params.img_uri, "localhost:3000/testing"), win, fail, options);
}
In the above example, using FileTransfer we can upload an image to a server. If successful, it will call the win
function, and if not successful, call the fail
function.
How do the win and fail functions receive the response
or error
parameters? We're not calling win(response)
or fail(error)
, so how does javascript accept these parameters without us setting them on our ft.upload()
line?
More example code:
function win(response){
console.log("Success!");
console.log(response);
};
function fail(error){
console.log("Failed.");
console.log("Error: ", error);
};
function uploadPhoto(params){
var options = {params: params};
var ft = new FileTransfer();
ft.upload(params.img_uri, "localhost:3000/testing"), win, fail, options);
};
In this second example, I've found that the win
function can be called, however its 'response' parameter comes up undefined. What is the reason for this?
What if I wanted to have my win
function to also accept params
from the upload function, so it would look more like this:
var win = function(response, parameters){
console.log("Success with parameters: ", parameters);
console.log("Response: ", response);
}
Would my ft.upload
line need to look more like this:
ft.upload(params.img_uri, "localhost:3000/testing", win(null, params), fail, options);
Lots of little questions here, Thanks for your help!
ft.upload
callswin
orfail
and supplies it with a value forresponse
orerror
. That is,ft.upload
might look something like this:Now, when you call
ft.upload(params.img_uri, "localhost:3000/testing", win, fail, options)
,win
is passed toupload
as thesuccessCallback
argument andfail
asfailureCallback
, andupload
in turn calls one or the other with an appropriate argument.Close, but not quite. If you do that, you're passing whatever
win
andfail
return as arguments, and unless they return functions that will be a problem whenft.upload
tries to call them....which, not coincidentally, is one solution: Make them return functions that
ft.upload
can call:The other option is to use
Function.prototype.bind
. You may have seenbind
used to set a function'sthis
object, but we can also pass additional arguments tobind
and the returned function will use those arguments as its own, initial arguments. In computer science this is called "currying." For example:(Since this function doesn't care about
this
, we just passnull
for the first argument.)With callbacks we can use this to get a "copy" of a function but with its first argument(s) "built in":
This way, when
ft.upload
callswin(response)
, it will actually be callingsuccessCallback(params, response)
.First of all: there is a syntax error at
ft.upload(params.img_uri, "localhost:3000/testing"), win, fail, options);
. Remove the parenthesis after"localhost:3000/testing"
.I don't know anything about the upload function you use, so I do not know if you pass the other parameters correctly. Let's assume all is done well.
Your first question was how the win and fail functions are called.
In JavaScript you can pass functions to another function. That's what you are doing here. You pass function that you define the the upload function. It's the responsibillity of the upload function to handle these function parameters.
I would assume that it creates a http object sends the data to the server as an octet stream and when the transfer will have completed it will call one of the function either win if the transfer was successfull or fail if the transfer failed. It depends on its implementation which parameter it will passes when it calls win or fail. In you case it might be the response of the http object or an error on failure.
Your second question was how you can pass your params to the callback.
In the first case you define the functions in a context where the params variable is defined (as parameter of the surrounding function). Functions in JavaScript are closures or lambda function which means, that they can use variables of the scope/context where they are defined. So in the first example you don't need to pass the params variable. You can use it directly in you functions. In the second example the function has no access to the params variable because the callback are defined outside of their scope. Then you have to create partial functions (which is to much to explaine it here, but if you are interested I'll add an example. Just drop a comment ;-)) or bind the params object to the callback. If you bind it to the callback you can access the params object inside the callback as
this
. There is also a special form of partial functions which is called function currying which would work here.It's not receiving this automatically, It's someone who wrote the code there which is calling
win
orfail
fromupload
function in the following way:If, in
upload
, you're not calling this then these functions won't get called. JavaScript do what you say it to do.win
function can be called in the first example either. If you calling win like this:win()
, then you will getundefined
response; however if you send some data, like:win({foo: "foo"})
, then you'll not get undefined, instead you'll get data that you've passed it.you've to pass
params
toupload
, and then callwin
from there using:and
win
definition would be like:or
Yes, you can do this but it'll pass
upload
then value returned by win. In your case, this is probably not required.