0

I am building an app using babel preset ES2015.

class Foo {
  bar(arg) {
    console.log(arg)
  }

  baz(arg) {
     this.bar(arg)
  }
}

function callBaz(callback) {
  callback("hello, wolrd")
}

instance = new Foo()

callBaz(instance.baz)
// Uncaught TypeError: Cannot read property 'bar' of undefined

I'd like to be able to pass a reference to baz in the context of Foo instance. Two options for that:

Options 1:

class Foo {
  bar(arg) {
    console.log(arg)
  }

  baz() {
     let self = this
     return(function(callback) {
       self.bar(callback)
     }
  }
}

function callBaz(baz) {
   baz("hello, wolrd")
}

instance = new Foo()

callBaz(instance.baz())
// hello, world

Options 2:

class Foo {
  bar(arg) {
    console.log(arg)
  }

  baz(arg) {
     this.bar(arg);
  }
}

function callBaz(callback) {
   callback("hello, wolrd")
}

instance = new Foo()
var baz = instance.baz.bind(instance)
callBaz(baz)
// hello, world 

Basically I don't like any of those solution and I am looking for another way to inject the context of the instance together with the callback method.

I could imagine doing something like this by either:

  • Using some native javascript paradigm/syntax (ES2015, 2016?) which I am familiar with
  • Using any Babel transform plugin ?
  • Adding an intermediate layer on the parent Foo class ?
  • Using any third-party library helping with that ?

Of course my problem isn't really one, since it's due to the nature of Javascript it-self, but I am wondering if there would be any "seamless" alternative or syntax to proceed with the binding.

NB: bar and baz could be static, but as far as I see the problem the same

Thanks !

nakwa
  • 1,005
  • 1
  • 12
  • 24
  • Imagine you could write it whatever way you want. How would you envision that? As it is, if you want to pass an arbitrary callback with a fixed scope, you'll need to use `bind` or pass a function expression which wraps the original call: `() => instance.baz()` – Mike Cluck Feb 16 '17 at 16:56
  • Well, this behaviour just doesn't really make sens to me. If I am passing `instance.baz` to `callBaz(callback)`, I'd like callBaz to act as an abstract layer and be be able to bind baz and its instance together ... – nakwa Feb 16 '17 at 17:12
  • I could pass two parameters to `callBaz(callback, reference)` and call it as `callBaz(instance.baz, instance)` but this is not really intuitive. Or adding an extra layer, passing something like `callBaz(instance.export('baz'))` ... – nakwa Feb 16 '17 at 17:18
  • 1
    @nakwa No, *you* are responsible for binding `baz` and its instance together. Not the abstract `callBaz` function that deals with all kinds of callbacks. – Bergi Feb 16 '17 at 17:24
  • This mostly depends on what is `baz` (foobar abstraction doesn't really help here). If it is supposed to be a callback by design (event handler, etc), it is better to bind it on design time. It can be bound with `bind` in constructor or it can be an arrow instance method. It always depends on the situation. See this question for example how it can be handled http://stackoverflow.com/a/42262044/3731501 – Estus Flask Feb 16 '17 at 17:25

0 Answers0