Passing parameters to a javascript callback function [duplicate] - javascript

This question already has answers here:
Pass an extra argument to a callback function
(5 answers)
Closed 6 years ago.
I've been trying to work out how to pass additional parameters to a javascript callback function.
In similar posts users have succeeded using anonymous function (these are new to me so I may have been doing them wrong) but I just can't get them to fire.
The below is what I have now, I need to be able to pass the itemId to the function "ajaxCheck_Callback" as well as the response.
Hope this makes sense.
Thanks for the help.
function delete(itemId)
{
selectpage.ajaxCheck(itemId, ajaxCheck_Callback);
}
Function ajaxCheck_Callback(response)
{
alert(response);
alert(itemId);
}
Thanks for the help guys. I now get undefined on my alert whereas previously this was alerting correctly.
function delete(itemId)
{
selectpage.ajaxCheck(itemid, function () {ajaxCheck_Callback(itemid); });
}
function ajaxCheck_Callback(response)
{
alert(response);
alert(itemId);
}

The way is usually done is to use an anonymous function.
function deleteItem(itemId) {
selectpage.ajaxCheck(itemId, function() { ajaxcheck_Callback(itemId); });
}
function ajaxCheck_Callback(response)
{
alert(response);
}
Careful with your syntax, there are some errors in there. The function keyword has a lower-case f and you can't have a function named delete, that's a reserved keyword.

As your question mentions, you can do it using an anonymous function:
function deleteItem(itemId)
{
selectpage.ajaxCheck(itemId, function ()
{
ajaxCheck_Callback(itemId);
});
}
// Note, lowercase 'f' in 'function'
function ajaxCheck_Callback(response)
{
alert(response);
}
It can also be done using a named function, which you might find more readable:
function deleteItem(itemId)
{
function onAjaxCheck()
{
ajaxCheck_Callback(itemId);
}
selectpage.ajaxCheck(itemId, onAjaxCheck);
}
N.B. as #Xeon06 points out, delete is a reserved word, so that is not a valid function name.

Create an anonymous function, which calls your callback, and supplies the needed parameter.
function deleteItemById(itemId)
{
selectpage.ajaxCheck(itemId, function() { ajaxCheck_Callback(itemId); });
}
The anonymous function will create a closure over itemId, and therefore will still have access to this value even after the original call to delete has long since ended.
For completeness, also note that delete is a reserved word in JavaScript; you need to name this function something else.

Related

Calling function by string not working

I'm trying to write a js function that triggers another, variable, function when complete. I figured I could do this by passing the second function's name as a string, but I can't get it to work. Here's my code:
logMeIn('likeThisPost');
function logMeIn(callBack) {
//First function content
$.post("/ajaxurl/",
{
login_id: login_id,
intent: 'login'
},
function(){
console.log('Logged in, refreshing header');
$.post("/secondajaxurl/",{},
function(data){
//success
if(typeof callBack!=='undefined') {
window[callBack]();
}
}
);
}
);
});
}
This should, according to my thinking, run likeThisPost after successfully completing both ajax calls in logMeIn, but instead I get this error:
window[callBack] is not a function
The function I'm calling on success definitley exists, and besides which, it doesn't look like it's even trying to call that function, but it's treating callBack as literal rather than a string.
I'm using jQuery and have everything wrapped in a $. Where am I going wrong?
With thanks to Jonas W and Rory McCrossan, the answer was to change the passed function to the function name, rather than a string, and then call the function directly rather than using window.
So logMeIn(likeThisPost) instead of logMeIn("likeThisPost") and callBack(); rather than window[callBack]();.
Thanks!

Replace named function with anonymous in javascript

I've seen EVERY example of how to replace anonymous functions with named ones. I'm looking for how a named function can be changed to an anonymous one. I'm looking to just optimize my code slightly. I understand how the anonymous function works, I just can't get the syntax right in this example.
Additionally, the doWork function is a big beast. I need it to stay named.
NOTE: I did google, and I'm either searching the wrong terms, or not a lot of people want to know how to do this. I humbly beg for SO's forgiveness of my failure to find this answer somewhere else.
NOTE2: Please ignore my use of closure with this.formFields. Just assume it won't change ever. I'm setting it at an earlier time.
My code:
function doWork(serviceResponse, theFormFields){
// Process stuff like jQuery or console test stuff etc
}
// THIS NAMED FUNCTION IS WHAT I WANT TO BE ANONYMOUS
function createCallback(formfields) {
return function(data) {
// This reference to the 'formfields' parameter creates a closure on it.
doWork(data, formfields);
};
}
// THE ABOVE FUNCTION *COULD* be anonymously declared in the getJSON
$.getJSON(jsonService + callString, createCallback(this.formFields));
$.getJSON(
jsonService + callString, // your param #1
(function (formField) { // here we create and execute anon function
// to put this.formFields into the scope as formField variable
// and then return required callback
return function (data) {
doWork(data, formField);
}
})(this.formFields)
);

using function as parameter - issues

I have the following code in JS:
if (Subs.Lsr!==null) {
Subs.Measure.Do("markLSRPosts",function() {
Subs.Lsr.Dom($ce);
});
}
Because this kind of code is inside my file multiple times I wanted to create a function for that:
function SingleMeasure(measureTitle, functionName) {
if (setting!==null) {
Subs.Measure.Do(measureTitle,function() {
functionName();
});
}
}
SingleMeasure(Subs.Lsr, "markLSRPosts", Subs.Lsr.Dom($ce));
Now my problem is that the function Subs.Lsr.Dom($ce) is called BEFORE my SingleMeasure()-Function is called (and so always, no matter what the condition of setting is).
I have to admit: This makes sense to me from coding logic. Nonetheless I wonder if there is another way to achieve what I want. (the method ...Dom() only being called when the setting-condition is met)
Now my problem is that the function Subs.Lsr.Dom($ce) is called BEFORE my SingleMeasure()
That's because you are calling it right here: Subs.Lsr.Dom($ce)
SingleMeasure(Subs.Lsr, "markLSRPosts", Subs.Lsr.Dom($ce));
You might pass it as an anonymous function:
SingleMeasure(Subs.Lsr, "markLSRPosts", function() {
Subs.Lsr.Dom($ce);
});
The callback will be invoked by your SingleMeasure function at a later stage.

How to execute a method passed as parameter to function

I want to write my own function in JavaScript which takes a callback method as a parameter and executes it after the completion, I don't know how to invoke a method in my method which is passed as an argument. Like Reflection.
example code
function myfunction(param1, callbackfunction)
{
//do processing here
//how to invoke callbackfunction at this point?
}
//this is the function call to myfunction
myfunction("hello", function(){
//call back method implementation here
});
You can just call it as a normal function:
function myfunction(param1, callbackfunction)
{
//do processing here
callbackfunction();
}
The only extra thing is to mention context. If you want to be able to use the this keyword within your callback, you'll have to assign it. This is frequently desirable behaviour. For instance:
function myfunction(param1, callbackfunction)
{
//do processing here
callbackfunction.call(param1);
}
In the callback, you can now access param1 as this. See Function.call.
I too came into same scenario where I have to call the function sent as parameter to another function.
I Tried
mainfunction('callThisFunction');
First Approach
function mainFuntion(functionName)
{
functionName();
}
But ends up in errors. So I tried
Second Approach
functionName.call().
Still no use. So I tried
Third Approach
this[functionName]();
which worked like a champ. So This is to just add one more way of calling. May be there may be problem with my First and Second approaches, but instead googling more and spending time I went for Third Approach.
function myfunction(param1, callbackfunction)
{
//do processing here
callbackfunction(); // or if you want scoped call, callbackfunction.call(scope)
}
object[functionName]();
object: refers to the name of the object.
functionName: is a variable whose value we will use to call a function.
by putting the variable used to refer to the function name inside the [] and the () outside the bracket we can dynamically call the object's function using the variable. Dot notation does not work because it thinks that 'functionName' is the actual name of the function and not the value that 'functionName' holds. This drove me crazy for a little bit, until I came across this site. I am glad stackoverflow.com exists <3
All the examples here seem to show how to declare it, but not how to use it. I think that's also why #Kiran had so many issues.
The trick is to declare the function which uses a callback:
function doThisFirst(someParameter, myCallbackFunction) {
// Do stuff first
alert('Doing stuff...');
// Now call the function passed in
myCallbackFunction(someParameter);
}
The someParameter bit can be omitted if not required.
You can then use the callback as follows:
doThisFirst(1, myOtherFunction1);
doThisFirst(2, myOtherFunction2);
function myOtherFunction1(inputParam) {
alert('myOtherFunction1: ' + inputParam);
}
function myOtherFunction2(inputParam) {
alert('myOtherFunction2: ' + inputParam);
}
Note how the callback function is passed in and declared without quotes or brackets.
If you use doThisFirst(1, 'myOtherFunction1'); it will fail.
If you use doThisFirst(1, myOtherFunction3()); (I know there's no parameter input in this case) then it will call myOtherFunction3 first so you get unintended side effects.
Another way is to declare your function as anonymous function and save it in a variable:
var aFunction = function () {
};
After that you can pass aFunction as argument myfunction and call it normally.
function myfunction(callbackfunction) {
callbackfunction();
}
myfunction(aFunction);
However, as other answers have pointed out, is not necessary, since you can directly use the function name. I will keep the answer as is, because of the discussion that follows in the comments.
I will do something like this
var callbackfunction = function(param1, param2){
console.log(param1 + ' ' + param2)
}
myfunction = function(_function, _params){
_function(_params['firstParam'], _params['secondParam']);
}
Into the main code block, It is possible pass parameters
myfunction(callbackfunction, {firstParam: 'hello', secondParam: 'good bye'});
callbackfunction = () => {}
callbackfunction2(){
}
function myfunction1(callbackfunction) {
callbackfunction();
}
//Exe
myfunction1(callbackfunction);
myfunction1(callbackfunction2.bind(this));
Super basic implementation for my use case based on some excellent answers and resources above:
/** Returns the name of type member in a type-safe manner. **(UNTESTED)** e.g.:
*
* ```typescript
* nameof<Apple>(apple => apple.colour); // Returns 'colour'
* nameof<Apple>(x => x.colour); // Returns 'colour'
* ```
*/
export function nameof<T>(func?: (obj: T) => any): string {
const lambda = ' => ';
const funcStr = func.toString();
const indexOfLambda = funcStr.indexOf(lambda);
const member = funcStr.replace(funcStr.substring(0, indexOfLambda) + '.', '').replace(funcStr.substring(0, indexOfLambda) + lambda, '');
return member;
}

How do I update the JavaScript this-pointer inside an object to point to another object?

I'm having some trouble with JavaScript and the passing of a function as parameter of another function.
let's say we are inside a class and do something like that:
this.get('target').update(this.onSuccess, this.onFail);
'target' is a JavaScript-object that has a method called update()
I'm calling this method and pass tow methods of the caller-class along as parameters
inside that update-method some stuff happens and when it's done that method should either call the onSuccess-method or the onFail-method. this looks something like:
update: function(onSuccess, onFail) {
if(true) {
onSuccess();
} else {
onFail();
}
}
until now, everything works pretty fine! but inside those success/fail-methods, that are defined in the caller-class (the one that calls above update-method), I'm using a this-pointer:
onFail: function() {
alert('Error: ' + this.get('target').error);
}
that this-pointer causes some issues. it doesn't point to the class where the method initially was defined but to the 'target'-object.
what I need to do now is to update the this-pointer right before the onSuccess / onFail calls inside the 'target'-class to make the methods work again. but this doesn't work due to a 'invalid assignment left-hand side'-error.
what is the best practice for a scenario like that? any ideas? thx in advance!!!
cheers
You have two options when calling update():
javascript function call()
javascript function apply()
the main difference being how you pass parameters to it. But they both allow scope/context injection.
Your code should look something like this:
this.get('target').update.call(this, this.onSuccess, this.onFail);
You can create a function that "binds" a function to a certain object (using a closure) and than pass these bound functions to the handler:
function bind(obj, fun) {
return function() {
return fun.apply(obj, arguments);
};
};
update(bind(this, this.onSuccess), bind(this, this.onFail));
To redirect this, you need a bind() (or similar) method in the Function class, as found in almost all JavaScript libraries:
if(!Function.prototype.bind){
Function.prototype.bind = function(scope) {
var _function = this;
return function() {
return _function.apply(scope, arguments);
}
}
}
Now do something like this:
update: function(onSuccess, onFail) {
if(true) {
onSuccess.bind(this)();
} else {
onFail.bind(this)();
}
}
The mechanism is explained here: Binding Scope in JavaScript

Categories

Resources