Cody
Cody

Reputation: 1879

Can't access `this` in Vue 3 methods with regular OR arrow functions

I'm not able to reference my data fields in my Vue 3 methods because of some misunderstanding in syntax and scope.

I'm using Typescript. I know this question has been asked to death but I can't for the life of me find out how to make the arrow functions of TS work to give me access to the Vue context as this

My code is simple:

  export default {
  data() {
    return {
      email: "",
      password: "",
    };
  },
  methods: {
    userLogin() {
      firebase
        .auth()
        .signInWithEmailAndPassword(this.email, this.password) //ERROR! Undefined
        .then((user: firebase.auth.UserCredential) => {
          //do stuff
        })
        .catch((error: AxiosError) => {
          //do other stuff
        });
    }

The guide here calls out this issue by saying:

An arrow function uses what is called lexical scoping. We'll get into this more in a bit, but it >basically means that the arrow function takes this from it's context.

If you try to access this from inside of an arrow function that's on a Vue component, you'll get an >error because this doesn't exist!

but it falls frustratingly short of actually providing an example fix. What do I do to access those data variables in my methods? I've tried the following and none of them work:

userLogin() {
      const self = this
      firebase
        .auth()
        .signInWithEmailAndPassword(self.email, self.password)
...

userLogin = () => {
      firebase
        .auth()
        .signInWithEmailAndPassword(this.email, this.password)
...

Upvotes: 1

Views: 8423

Answers (1)

Helper function
Helper function

Reputation: 230

When using TypeScript to define a component, always use

import { defineComponent } from "vue";
export default defineComponent({
data() {
    return {
      email: "",
      password: "",
    };
  },
...

That should solve the problem.

If it doesn't, then try this:

 methods: {
    userLogin() {
         const email = this.email;
         const password = this.password;
         firebase
        .auth()
        .signInWithEmailAndPassword(email, password)
        .then((user: firebase.auth.UserCredential) => {
          //do stuff
        })
        .catch((error: AxiosError) => {
          //do other stuff
        });
    }

Upvotes: 5

Related Questions