I'm calling PageMethod "SameMethod" from javascript method "caller" so that I can get some values from DB. After I get values, control is continuing in "onSuccess" method. Problem is that I need to use some variable values ("importantValue") from javascript method "caller" in "onSuccess" method.
function caller(){
var importantValue = 1984;
PageMethod.SomeMethod(param1,..., onSuccess, onFailure)
}
onSuccess method should be something like this:
function onSuccess(pageMethodReturnValue, importantValue ){
}
Is it possible and, if it is, how to pass multiple parameters (besides return values of page method) to "onSuccess" method of PageMethod?
Thanks for help
Pass your importantValue as an additional parameter when calling the PageMethod. (this is usually called the context parameter if you are searching online for more info)
function caller(){
var importantValue = 1984;
PageMethod.SomeMethod(param1,..., onSuccess, onFailure, importantValue)
}
Then you can access the value in the onSuccess callback as follows:
function onSuccess(pageMethodReturnValue, context, methodName){
// context == 1984
}
Update to explain onSuccess parameters for #JacksonLopes
There is a good description on the aspalliance website in an article by Suresh Kumar Goudampally
The important bit (modified to use my parameter names) is:
The success call back method has three parameters:
pageMethodReturnValue - Returns the output of the page method.
context - This is used to handle different logic when single callback is used for multiple page method requests. We can also pass
an array of values as the context parameter.
methodName - This parameter returns the name of page method called.
You could use an anonymous function
PageMethod.SomeMethod(param1,..., function(){onSuccess(foo, importantValue)}, onFailure)
Related
I have this piece of code below:
It makes a GET call to an URL, gets some object, and appends an image to an HTML tag.
function getDataFromApi(searchTerm, callback) {
const URL1 = `some url`;
const design = {
url: URL1,
data: {
"dog breed name": searchTerm
},
type: 'GET',
success: callback
};
$.ajax(design);
}
function displaySearchData(data) {
const allResultsLength = data.message.length;
const ranNum = Math.floor(Math.random() * allResultsLength);
const dogResults = data.message[ranNum];
$(`.js-search-results`).html(`<img src = ${dogResults}>`);
}
function watchSubmit() {
$('.js-search-form').submit(event => {
event.preventDefault();
let queryTarget = $(event.currentTarget).find('.js-query');
let query = queryTarget.val();
queryTarget.val("");
getDataFromApi(query, displaySearchData);
});
}
$(watchSubmit);
I get the getDataFromApi and watchSubmit but getDataFromApi(query, displaySearchData); isn't intuitive to me at all.
I've been writing Java, and it doesn't make sense to me how displaySearchData is getting called without the parameter - it seems that line should be getDataFromApi(query, displaySearchData(data));.
Can someone please explain how this is getting compiled & executed (basically how this is a legitimate syntax) in javascript?
Somewhere in the good'ol jquery, there lies this piece of code:
$.ajax = function(config){
...
// get the response from XHR request,
// and save it in, say, 'response'
...
// now check, if the response is OK 200
// and if so, execute next line
// which is basically - calling your displaySearchData method
config.success(response);
...
}
now, config is your design object, which has a property success which carries the reference to your displaySearchData method.
The data argument of method displaySearchData will now carry the reference to variable response passed in the method invocation config.success(response).
EDIT: the argument callback also carries forward the reference of the method displaySearchData to getDataFromApi
Concept to be noted:
functions can be passed in Javascript as arguments to another function, in which case we only need the referring variable to be passed as argument. Invocation parentheses () are not required.
function A(data){...};
function b(referenceToFunctionA){
...
referenceToFunctionA(someData);
...
};
// correct
b(A);
// wrong, because adding () after any function reference variable
// invokes the method immediately.
// in this particular case the returned value of the method A
// is passed as argument instead of the reference to method A itself.
b(A());
Welcome to JavaScript My Friend. Get ready to experience more magical weirdness as you continue to work on JS. Good luck.
What you need to look at is in the function getDataFromApi().
In that function, you have a "callback" parameter. This parameter is later added into $.ajax. This is a jQuery function that will provide some callback when a certain condition is matched (like before sending a request, when the response has been received,...). This $.ajax callback provide you with 3 parameters, one of them is data (which are being used, textStatus, and jqXHR. Usually, you only need to pay attention to the data since it contains the response from where you are requesting data.
So when the $.ajax success, the "callback" function will be called, which is the displaySearchData. And since $.ajax callback provides you with the data parameter, you can add them to the parameters of displaySearchData. Do note that you can add the extra 2 provided parameters if needed.
You can have a look at that function here: jQuery Ajax
To keep my code concise and modular, I am using following way of processing HTTP calls.
From controllers I do:
function makeCall(){
Service.getDetails( url, obj).then(responseFn, errorFn);
}
In Service I do:
this.getDetails = function(url, obj){
return $http.get(url);
}
Then in Controller I have:
function responseFn(){
//response objct available here by deafult
}
function errorFn(){
//error objct available here by deafult
}
In these function I automatically get response and error object. In one case it is fine since I need only the response of GET but in one another case I ma calling same method from a different controller, and there I need to use a condition to manipulate the response.
Query: How do I pass a parameter i.e. 'obj' to these callback function from my original makeCall function. If I pass two dummy variables to callback function it do not work. (I expected first argument to be replaced by response and second argument as my argument)
One of your options is extend your returning object, in this case you will have a data access across the controller.
in your service:
this.getDetails = function(url, obj){
this.myObjData = obj; // bind it to your returing object
return $http.get(url);
}
in your controller:
function makeCall(){
Service.getDetails(url, obj).then(responseFn, errorFn); // respond parameter will attach by default, no need to bind it here
}
function responseFn(respond){
console.log(respond); // will attach by default
console.log(Service.myObjData); // access your data from here
}
Hope it help you.
How does the callback in fs.readfile get called when using fs.readfile.bind(context,pathArgument) like so. //understandable because my task function knows the name of the callback parameter
async.series([function(callback){
//operation done callback()},...],finalCallback(err,result));
BUT
//not understandable
async.series([fs.someOperation.bind(null,firstArgument),...],finalCallback(err,esult))
I believe I understand partial application;however, it would look something like this. function(callback){ fs.someOperation(firstArgument, ????)}(asyncCallbackFunc) and then I have no idea how the second argument is called...
Thx, in advance for helping me clear this up.
All bind does is set the context of the callback. It is still a regular callback like any other. Except, it is explicitly told what this will be. Looks like in your case, it is set to null.
The bind function on function object allows you to set the context i.e the value of this inside the function body as well as allow you to create a partial function in case you pass some arguments while calling bind.
For example:
function add(a,b) {
console.log(this);
return a+b;
}
var newAdd = add.bind("hello world", 10);
The newAdd will be one argument function which gets added to 10 and the result is returned. Also when newAdd is called the "hello world" will be logged in console.
Now when your code says fs.readFile.bind(null, path) it means that the return function will be of one argument which is the callback for readfile i.e the return function will be of form function(callback) { ... } which is exactly what is required to be passed to async.series
The main idea in the code you posted is to create a partial function that accepts only callback so that it can be passed to async.series the null argument doesn't play any role but you need to pass a context argument to call bind function, hence a null is passed as context arg.
I am unable to pass two arguments to the adapter onSuccess() function using IBM Worklight. Please show me the way. Here is what I am currently trying:
var options = {
onSuccess : SubCategoriesSuccess(options, result),
onFailure : SubCategoriesFailure,
invocationContext: {}
};
The onSuccess parameter requires a reference to a function, not an invocation of a function - note that there is a difference between SubCategoriesSuccess and SubCategoriesSuccess() in JavaScript. What you are doing is passing the result of calling SubCategoriesSuccess(options, result).
What you need is what is typically referred to as partial invocation in programming jargon. JavaScript itself has a function for doing this - Function.prototype.bind(). You should probably look at that (although there alternatives provided by various JavaScript toolkits too).
This would mean your code would look something like:
{
onSuccess : SubCategoriesSuccess.bind(this, options, result),
onFailure : SubCategoriesFailure,
invocationContext: {}
};
Note that I have not tested this.
If options is a variable already on your calling function. You have to wrap the return function in another. So in other words, success is returned from the adapter, and options is just passed along by the calling function.
onSuccess:function(result){
SubCategoriesSuccess(options, result);
}
I found this little example on jquery documentation page. I always tried returning value from ajax function and I was always told that there is some problem of sync and async thing and I can't return value out of $.ajax function without making it async.
$.ajax({
url: "test.html",
context: document.body
}).done(function() {
$(this).addClass("done");
});
In the example above, on what this done function is applied(whats being used as $(this) in example).
one more thing, as the ajax function can't set global variables, can't the be set in this done too? cant I return value out of done function either?
what this done function is applied
$.ajax returns a jqXHR object (see first section after the configuration parameter description) wich implements the promise interface and allows you to add callbacks and get notified of changes of the Ajax call.
whats being used as $(this) in example
Inside the callbacks for $.ajax, this refers to the object context refers to in the configuration or the jqXHR instance if context was not set. In this case it refers to document.body:
context: This object will be made the context of all Ajax-related callbacks. By default, the context is an object that represents the ajax settings used in the call ($.ajaxSettings merged with the settings passed to $.ajax).
This and more is all explained in the documentation: http://api.jquery.com/jQuery.ajax/
as the ajax function can't set global variables
That is not correct, any function can set global variables. The problem with asynchronous functions is that you are likely accessing the variable before it was set.
can't the be set in this done too
See above
cant I return value out of done function either
You can return a value (as in putting a return statement inside the callback), but you cannot return it to your code, since jQuery is calling the callback internally and just ignoring the return value.