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?>);
Michał Perłakowski
  • 88,409
  • 26
  • 156
  • 177
Kulin
  • 611
  • 1
  • 5
  • 9
  • 1
    If you want to see a much thorough answer, see this question and answer, which is two years older: http://stackoverflow.com/questions/21985201/pass-extra-parameters-to-jquery-ajax-promise-callback – JotaBe Nov 28 '16 at 09:46

5 Answers5

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));
Teocci
  • 7,189
  • 1
  • 50
  • 48
str
  • 42,689
  • 17
  • 109
  • 127
  • 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 Nov 25 '16 at 10:07
  • @Kulin This should work every time. Did you get it to work as you marked this as answer? – str Nov 25 '16 at 11:38
  • This post is being discussed on Meta - http://meta.stackoverflow.com/q/338481 (see the comments to the question). Also notifying the asker, @Kulin . – duplode Nov 26 '16 at 08:56
4

You could use an anonymus function

something like

session.sub('Hello', function(){marketEvents(your args);});
Dropye
  • 214
  • 3
  • 18
  • 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 Oct 09 '17 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"));
TryingToImprove
  • 7,047
  • 4
  • 30
  • 39
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)
})
Teocci
  • 7,189
  • 1
  • 50
  • 48
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));
aecavac
  • 1,026
  • 8
  • 7