56

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?>);
1

5 Answers 5

69

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));
3
  • Thanks, thats 'work'! But only the first time that marketEvent it's called. Next calls return undefined for newArg value, but not for other two.
    – Kulin
    Commented Nov 25, 2016 at 10:07
  • @Kulin This should work every time. Did you get it to work as you marked this as answer?
    – str
    Commented Nov 25, 2016 at 11:38
  • This post is being discussed on Meta - meta.stackoverflow.com/q/338481 (see the comments to the question). Also notifying the asker, @Kulin .
    – duplode
    Commented Nov 26, 2016 at 8:56
4

You could use an anonymus function

something like

session.sub('Hello', function(){marketEvents(your args);});
1
  • This is by far the best answer, thank you! Could be also used with argument(s) on function(), e.g. session.sub('Hello', function(orgArg){marketEvents(orgArg, your_args);});
    – gregko
    Commented Oct 9, 2017 at 23:38
1

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"));
0
1

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)
})

0

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));

Not the answer you're looking for? Browse other questions tagged or ask your own question.