5

I creating an object that uses async function methods with babel-polyfill/babel-preset-es2017, however I am having a problem with this:

let obj = () => {
    return {
        doAsync: async () => {
            let thing = await longProcess()
            return this.transform(thing)
        },

        transform: (thing) => {
            return psuedoCodeTransform(thing)
        }
    }
}

let instance = obj()
instance.doAsync()
// TypeError: cannot read property 'transform' of undefined`.

Is this something described in ES2017, a babel-polyfill/regeneratorRuntime gotcha?

Felix Kling
  • 705,106
  • 160
  • 1,004
  • 1,072
Kris Molinari
  • 475
  • 9
  • 17

2 Answers2

5

Arrow functions do not create their own context. They don't have their own this and this will refer to the enclosing scope's context. In this case (no pun intended), this does not refer to the same object as instance at all.

If you log this inside doAsync, you'll notice it's the window global.

Joseph
  • 107,072
  • 27
  • 170
  • 214
  • 2
    Interesting. I am doing this inside an Angular service constructor, which gave me `console.log(this) // undefined`. That is what threw me off. – Kris Molinari May 23 '17 at 19:55
3

Joseph the Dreamer's response is exactly right obviously, but since I work best by example, here is your code changed which should make it work. Notice the only change is actually defining doAsync as a normal function instead of arrow function:

let obj = () => {
    return {
        doAsync: async function() {
            let thing = await longProcess()
            return this.transform(thing)
        },

        transform: (thing) => {
            return psuedoCodeTransform(thing)
        }
    }
}

let instance = obj()
instance.doAsync()
// TypeError: cannot read property 'transform' of undefined`.
Lance Whatley
  • 1,950
  • 9
  • 13
  • 1
    Or simply `async doAsync() { ... }`. I don't understand why someone wants to use arrow functions in object literals (unless for `this` of course). Method definitions are shorter. – Felix Kling May 23 '17 at 21:37