New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug: Accessing this inside async/await returns undefined #6806

Closed
adeelshahid opened this Issue Nov 12, 2017 · 15 comments

Comments

Projects
None yet
7 participants
@adeelshahid

adeelshahid commented Nov 12, 2017

same as the issue #2765

const LockIcon = styled.img.attrs({
  src: loginImg,
})``

class Login extends React.Component {
  async onLogin() {
    console.log('this', this)
    try {
      const result = await Database.login()
    } catch (err) {
      console.log('err', err)
    }
  }

  render() {
    return isEmpty(this.props.user) ? <LockIcon onClick={this.onLogin} /> : null
  }
}

Babel/Babylon Configuration (.babelrc, package.json, cli command)

  "presets": [
    [
      "env",
      {
        "modules": false,
        "loose": true,
        "targets": {
          "uglify": true
        }
      }
    ],
    "react"
  ],
  "plugins": [
    "react-hot-loader/babel",
    "transform-object-rest-spread",
    "transform-function-bind",
    "transform-class-properties",
    "transform-decorators-legacy",
    "transform-runtime"
  ]
}
{
  "your": { "config": "here" }
}

Expected Behavior

This should point to Class instance. Even using onLogin = async () => {} returns undefined.

Current Behavior

It returns undefined. Async functions should not change this context.

software version(s)
Babel 6.26.0
node 8.7.0
npm 4.6.1
Operating System Mac OSX High Sierra
@babel-bot

This comment has been minimized.

Show comment
Hide comment
@babel-bot

babel-bot Nov 12, 2017

Collaborator

Hey @adeelshahid! We really appreciate you taking the time to report an issue. The collaborators
on this project attempt to help as many people as possible, but we're a limited number of volunteers,
so it's possible this won't be addressed swiftly.

If you need any help, or just have general Babel or JavaScript questions, we have a vibrant Slack
community that typically always has someone willing to help. You can sign-up here
for an invite.

Collaborator

babel-bot commented Nov 12, 2017

Hey @adeelshahid! We really appreciate you taking the time to report an issue. The collaborators
on this project attempt to help as many people as possible, but we're a limited number of volunteers,
so it's possible this won't be addressed swiftly.

If you need any help, or just have general Babel or JavaScript questions, we have a vibrant Slack
community that typically always has someone willing to help. You can sign-up here
for an invite.

@loganfsmyth

This comment has been minimized.

Show comment
Hide comment
@loganfsmyth

loganfsmyth Nov 12, 2017

Member

Your example is expected to fail, but the onLogin = async () => {} you mentioned should work. Are you sure it failed?

Member

loganfsmyth commented Nov 12, 2017

Your example is expected to fail, but the onLogin = async () => {} you mentioned should work. Are you sure it failed?

@Andarist

This comment has been minimized.

Show comment
Hide comment
@Andarist

Andarist Nov 12, 2017

Member

I've checked that this doesn't work with non-arrow functions, can be verified here

Member

Andarist commented Nov 12, 2017

I've checked that this doesn't work with non-arrow functions, can be verified here

@loganfsmyth

This comment has been minimized.

Show comment
Hide comment
@loganfsmyth

loganfsmyth Nov 12, 2017

Member

@Andarist If it's not an arrow function then that's expected. If it's an arrow it gets turned into console.log('this', _this); though which should work fine.

Member

loganfsmyth commented Nov 12, 2017

@Andarist If it's not an arrow function then that's expected. If it's an arrow it gets turned into console.log('this', _this); though which should work fine.

@Andarist

This comment has been minimized.

Show comment
Hide comment
@Andarist

Andarist Nov 12, 2017

Member

@loganfsmyth Non-arrow functions works though too, this is not rewritten but as the function gets attached to the instance (with defineProperty) it points to the instance. I guessed that async should behave the same.

Example

Member

Andarist commented Nov 12, 2017

@loganfsmyth Non-arrow functions works though too, this is not rewritten but as the function gets attached to the instance (with defineProperty) it points to the instance. I guessed that async should behave the same.

Example

@loganfsmyth

This comment has been minimized.

Show comment
Hide comment
@loganfsmyth

loganfsmyth Nov 13, 2017

Member

@Andarist The code sample in the issue is <LockIcon onClick={this.onLogin} /> so it'll call onLogin with no context, which means binding is a requirement for it to work for the given usecase.

Member

loganfsmyth commented Nov 13, 2017

@Andarist The code sample in the issue is <LockIcon onClick={this.onLogin} /> so it'll call onLogin with no context, which means binding is a requirement for it to work for the given usecase.

@Andarist

This comment has been minimized.

Show comment
Hide comment
@Andarist

Andarist Nov 13, 2017

Member

You are right, I've misread async's output and the this there points to the instance too.

Member

Andarist commented Nov 13, 2017

You are right, I've misread async's output and the this there points to the instance too.

@yakovenkoroman1993

This comment has been minimized.

Show comment
Hide comment
@yakovenkoroman1993

yakovenkoroman1993 Jan 19, 2018

I have the same problem. With async/await console.log(this) inside arrow function outputs undefined
image

yakovenkoroman1993 commented Jan 19, 2018

I have the same problem. With async/await console.log(this) inside arrow function outputs undefined
image

@eldyvoon

This comment has been minimized.

Show comment
Hide comment
@eldyvoon

eldyvoon Mar 14, 2018

+1, doesn't work with react? I've this config in .babelrc

["transform-runtime", { "polyfill": false, "regenerator": true }]

eldyvoon commented Mar 14, 2018

+1, doesn't work with react? I've this config in .babelrc

["transform-runtime", { "polyfill": false, "regenerator": true }]

@adeelshahid

This comment has been minimized.

Show comment
Hide comment
@adeelshahid

adeelshahid Mar 14, 2018

@loganfsmyth @Andarist the process below works. If this solution looks good to you guys we can close this bug.

@eldyvoon

try the following process,

  1. Bind async function inside the constructor.
  2. Write async function as a normal function.

Example

constructor(props) {
  super(props)
  this.asyncFunc = this.asyncFunc.bind(this)
}

async function asyncFunc() {
  try {
    const result = await window.fetch(...)
  } catch (e) {}
}

adeelshahid commented Mar 14, 2018

@loganfsmyth @Andarist the process below works. If this solution looks good to you guys we can close this bug.

@eldyvoon

try the following process,

  1. Bind async function inside the constructor.
  2. Write async function as a normal function.

Example

constructor(props) {
  super(props)
  this.asyncFunc = this.asyncFunc.bind(this)
}

async function asyncFunc() {
  try {
    const result = await window.fetch(...)
  } catch (e) {}
}
@eldyvoon

This comment has been minimized.

Show comment
Hide comment
@eldyvoon

eldyvoon Mar 14, 2018

@adeelshahid why can't I use arrow function? handleChange = async (e) => {}

eldyvoon commented Mar 14, 2018

@adeelshahid why can't I use arrow function? handleChange = async (e) => {}

@adeelshahid

This comment has been minimized.

Show comment
Hide comment
@adeelshahid

adeelshahid Mar 14, 2018

@eldyvoon babel transpilation does not correctly handle this reference when using bind and async together. Therefore I offered a workaround.

adeelshahid commented Mar 14, 2018

@eldyvoon babel transpilation does not correctly handle this reference when using bind and async together. Therefore I offered a workaround.

@Kovensky

This comment has been minimized.

Show comment
Hide comment
@Kovensky

Kovensky Mar 15, 2018

Member

This was a bug with react-hot-loader@3; it should be fixed with react-hot-loader@4.

Member

Kovensky commented Mar 15, 2018

This was a bug with react-hot-loader@3; it should be fixed with react-hot-loader@4.

@yakovenkoroman1993

This comment has been minimized.

Show comment
Hide comment
@yakovenkoroman1993

yakovenkoroman1993 Mar 17, 2018

This issue is not reproduced in react-hot-loader 4. I checked it.

yakovenkoroman1993 commented Mar 17, 2018

This issue is not reproduced in react-hot-loader 4. I checked it.

@eldyvoon

This comment has been minimized.

Show comment
Hide comment
@eldyvoon

eldyvoon Mar 17, 2018

@yakovenkoroman1993 if you don't mind, just use arrow function in jsx and do async urFunc() { console.log(this) } it will work.

eldyvoon commented Mar 17, 2018

@yakovenkoroman1993 if you don't mind, just use arrow function in jsx and do async urFunc() { console.log(this) } it will work.

@lock lock bot added the outdated label Jun 16, 2018

@lock lock bot locked as resolved and limited conversation to collaborators Jun 16, 2018

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.