Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vue.js - Can't access computed properties from methods

I have a login method inside a Vue component that uses firebase to sign in a user. I'm using computed properties user, message, and hasErrors. When this method runs, It goes into the catch function, but this error comes up: Uncaught TypeError: Cannot set property 'message' of undefined. I've tried changing the vuex state directly (because that's what the computed prop does), but this gives the same error. Here is the method I'm using:

login: function (event) {
  // ... more stuff
  // Sign-in the user with the email and password
  firebase.auth().signInWithEmailAndPassword(this.email, this.password)
    .then(function (data) {
      this.user = firebase.auth().currentUser
    }).catch(function (error) {
      this.message = error.message
      this.hasErrors = true
    })
  // ...
}

Here's what the computed prop looks like:

message: {
  get () {
    return this.auth.message // mapState(['auth'])
  },
  set (value) {
    this.$store.commit('authMessage', value)
  }
}

I'm pretty sure the problem has to do with it being inside a Promise. So how can I access computed properties within the firebase Promise?

like image 232
Sheikh Avatar asked Sep 21 '17 11:09

Sheikh


People also ask

What is the difference between a computed property and methods in VUE JS?

A computed property is cached, which implies that, for accessing data, the function runs just once if the value remains unchanged. Methods, on the other hand, need to run data properties checks every time, because they cannot tell otherwise if the values are changed inside the method property.

Can you watch a computed property Vue?

Yes, you can setup watcher on computed property, see the fiddle.

How do computed properties work in Vue?

In Vue. js, computed properties enable you to create a property that can be used to modify, manipulate, and display data within your components in a readable and efficient manner. You can use computed properties to calculate and display values based on a value or set of values in the data model.


1 Answers

this inside a callback refers to the callback itself (or rather, as pointed out, the execution context of the callback), not the Vue instance. If you want to access this you either need to assign it to something outside the callback:

  // Assign this to self
  var self = this;

  firebase.auth().signInWithEmailAndPassword(this.email, this.password)
    .then(function (data) {
      self.user = firebase.auth().currentUser
    }).catch(function (error) {
      self.message = error.message
      self.hasErrors = true
    })

Or if you are using ES2015 use an arrow function, which do not define their own this context:

  firebase.auth().signInWithEmailAndPassword(this.email, this.password)
    .then(data => {
      this.user = firebase.auth().currentUser
    }).catch(error => {
      this.message = error.message
      this.hasErrors = true
    })
like image 189
craig_h Avatar answered Oct 29 '22 12:10

craig_h