Pass an extra argument to a callback function

JavascriptFunctionParametersCallback

Javascript Problem Overview


I have a function callWithMagic which takes a callback function as a parameter and calls it with one argument.

const callWithMagic = callback => {
  const magic = getMagic();
  callback(magic);
};

I also have a function processMagic which takes two arguments: magic and theAnswer.

const processMagic = (magic, theAnswer) => {
  someOtherMagic();
};

I want to pass the function processMagic as an argument to callWithMagic, but I also want to pass 42 as the second parameter (theAnswer) to processMagic. How can I do that?

callWithMagic(<what should I put here?>);

Javascript Solutions


Solution 1 - Javascript

Just create a function(magic) {} as a wrapper callback:

callWithMagic(function(magic) {
  return processMagic(magic, 42);
});

Or using ECMAScript 6: arrow functions:

callWithMagic(magic => processMagic(magic, 42));

Solution 2 - Javascript

You could use an anonymus function

something like

session.sub('Hello', function(){marketEvents(your args);});

Solution 3 - Javascript

You can create a function which calls the marketEvent function. No need to complicate things

session.sub('Hello', function(args, kwargs) {
    marketEvent(args, kwargs, 'my custom data');
});

otherwise you can do this:

var mrktEvent = function(customArgs) {
    return function(args, kwargs) { 
        marketEvent(args, kwargs, customArgs) 
    };
}

session.sub('Hello', mrktEvent("customEvent"));

Solution 4 - Javascript

> I want to pass the function processMagic as an argument to callWithMagic, but I also want to pass 42 as the second parameter theAnswer to processMagic. How can I do that?

Okay first, your implementation was almost close to the answer. You want to call your function like this callWithMagic(<what should I put here?>). Also I noticed that you use ECMAScript 6: arrow functions so we'll simplify our code a lot.

So, callWithMagic(<what should I put here?>); can use these parameters callWithMagic(processMagic, 42); where the first parameter is the callback function and the other one the extra parameter you want to add.

To call this function with the extra parameter, we need to modify the callWithMagic implementation by defining a new parameter that will be answer like this:

const callWithMagic = (callback, answer) => {
  const magic = getMagic()
  callback(magic, answer)
}

Now, here you have a working snippet of your implementation:

const spells = ["Accio", "Aguamenti", "Alohomora", "Aparecium", "Avada Kedavra", "Avifors", "Avis", "Bombarda", "Colloportus", "Confringo", "Confundus", "Crucio", "Deletrius", "Densaugeo", "Diffindo", "Dissendium", "Engorgio", "Episkey", "Evanesco", "Expecto Patronum", "Expelliarmus", "Fera Verto", "Ferula", "Fidelius", "Finite Incantatem", "Flagrate", "Flipendo", "Furnunculus", "Geminio", "Homorphus", "Immobulus", "Impedimenta", "Imperio", "Impervius", "Incarcerous", "Incendio", "Legilimens", "Levicorpus", "Liberacorpus", "Locomotor Mortis", "Lumos", "Mobiliarbus", "Mobilicorpus", "Morsmordre", "Muffliato", "Nox", "Obliviate", "Orchideous", "Petrificus Totalus", "Prior Incantato", "Protego", "Reducio", "Reducto", "Relashio", "Rennervate", "Reparo", "Repello", "Repello Muggletum", "Revelio", "Rictusempra", "Riddikulus", "Salvio Hexia", "Scourgify", "Sectumsempra", "Serpensortia", "Silencio", "Sonorus", "Stupefy", "Tarantallegra", "Tergeo", "Waddiwasi", "Wingardium Leviosa"]
const len = spells.length

function random(max) {
  return Math.floor(Math.random() * max)
}

const getMagic = () => {
  return spells[random(len)]
}

const callWithMagic = (callback, answer) => {
  const magic = getMagic()
  callback(magic, answer)
}

const someOtherMagic = (magic, answer) => {
  console.log({magic, answer})
}

const processMagic = (magic, answer) => {
  someOtherMagic(magic, answer)
}

callWithMagic(processMagic, 42)

Teo, seems good but it is to long, can we simplify this?

Well, yes. We just need the concept of closure. The idea is to create a wrapper callback like function() {}. This will be the parameter for callWithMagic. Now let's modify callWithMagic to receive the wrapper callback:

const callWithMagic = function(f) {
  f()
}

or using arrow functions:

const callWithMagic = f => f()

Let's see how it works:

const spells = ["Accio", "Aguamenti", "Alohomora", "Aparecium", "Avada Kedavra", "Avifors", "Avis", "Bombarda", "Colloportus", "Confringo", "Confundus", "Crucio", "Deletrius", "Densaugeo", "Diffindo", "Dissendium", "Engorgio", "Episkey", "Evanesco", "Expecto Patronum", "Expelliarmus", "Fera Verto", "Ferula", "Fidelius", "Finite Incantatem", "Flagrate", "Flipendo", "Furnunculus", "Geminio", "Homorphus", "Immobulus", "Impedimenta", "Imperio", "Impervius", "Incarcerous", "Incendio", "Legilimens", "Levicorpus", "Liberacorpus", "Locomotor Mortis", "Lumos", "Mobiliarbus", "Mobilicorpus", "Morsmordre", "Muffliato", "Nox", "Obliviate", "Orchideous", "Petrificus Totalus", "Prior Incantato", "Protego", "Reducio", "Reducto", "Relashio", "Rennervate", "Reparo", "Repello", "Repello Muggletum", "Revelio", "Rictusempra", "Riddikulus", "Salvio Hexia", "Scourgify", "Sectumsempra", "Serpensortia", "Silencio", "Sonorus", "Stupefy", "Tarantallegra", "Tergeo", "Waddiwasi", "Wingardium Leviosa"]
const len = spells.length

const random = max => Math.floor(Math.random() * max)

const callWithMagic = callback => callback()

const getMagic = () => spells[random(len)]

const someOtherMagic = (magic, answer) => console.log({magic, answer})

const processMagic = (magic, answer) => someOtherMagic(magic, answer)

callWithMagic(function() {
  const magic = getMagic()
  return processMagic(magic, 42)
})

Now let's simplify callWithMagic as const callWithMagic = f => f().

const magic = getMagic()
callWithMagic(magic => processMagic(magic, 42))

const spells = ["Accio", "Aguamenti", "Alohomora", "Aparecium", "Avada Kedavra", "Avifors", "Avis", "Bombarda", "Colloportus", "Confringo", "Confundus", "Crucio", "Deletrius", "Densaugeo", "Diffindo", "Dissendium", "Engorgio", "Episkey", "Evanesco", "Expecto Patronum", "Expelliarmus", "Fera Verto", "Ferula", "Fidelius", "Finite Incantatem", "Flagrate", "Flipendo", "Furnunculus", "Geminio", "Homorphus", "Immobulus", "Impedimenta", "Imperio", "Impervius", "Incarcerous", "Incendio", "Legilimens", "Levicorpus", "Liberacorpus", "Locomotor Mortis", "Lumos", "Mobiliarbus", "Mobilicorpus", "Morsmordre", "Muffliato", "Nox", "Obliviate", "Orchideous", "Petrificus Totalus", "Prior Incantato", "Protego", "Reducio", "Reducto", "Relashio", "Rennervate", "Reparo", "Repello", "Repello Muggletum", "Revelio", "Rictusempra", "Riddikulus", "Salvio Hexia", "Scourgify", "Sectumsempra", "Serpensortia", "Silencio", "Sonorus", "Stupefy", "Tarantallegra", "Tergeo", "Waddiwasi", "Wingardium Leviosa"]
const len = spells.length

const random = max => Math.floor(Math.random() * max)

const callWithMagic = f => f()

const getMagic = () => spells[random(len)]

const someOtherMagic = (magic, answer) => console.log({magic, answer})

const processMagic = (magic, answer) => someOtherMagic(magic, answer)

callWithMagic(() => {
  const magic = getMagic()
  processMagic(magic, 42)
})

Solution 5 - Javascript

You can bind argument object to callback function:

var varObject = {var1: "findButton", var2: true};

function cbFunc() {
    console.log(this.var1+ ":" + this.var2);
}
		
//Example callback
datatable.ajax.reload(cbFunc.bind(varObject));

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionKulinView Question on Stackoverflow
Solution 1 - JavascriptstrView Answer on Stackoverflow
Solution 2 - JavascriptDropyeView Answer on Stackoverflow
Solution 3 - JavascriptTryingToImproveView Answer on Stackoverflow
Solution 4 - JavascriptTeocciView Answer on Stackoverflow
Solution 5 - JavascriptaecavacView Answer on Stackoverflow