Search code examples
firebasevue.jsquasar-frameworkquasar

Unable to use this.$router.push(' ') inside docRef function


I am trying to use vue-router in my quasar project. this.$router.push( ' ' ) works everywhere on the page except inside this docRef block.

I found out that this.$router.push still works in the same component.

This router call works:

const userRef = this.$db.collection('users').doc(this.$fb.auth().currentUser.uid)
console.log('your id is' + this.$fb.auth().currentUser.uid)
userRef.set({
  accountUID: this.$fb.auth().currentUser.uid,
  accountChosen: true,
  accountType: 'user'
})
this.$router.push('../user/home')

This does not work (in the same component):

  var docRef = this.$db.collection('users').doc(uid)
  docRef.get().then(function (doc) {
    data = doc.data().accountType
    if (data === 'user') {
      console.log('account is users')
      console.log(data)
      this.$router.push('./user/home')
    } else if (data === 'truck') {
      console.log('account is a truck')
      this.$router.push('./truck/home')
    } else {
      console.log('in else statement')
    }
  }).catch(function (error) {
    console.log(error)
  })

Chrome Console Error

TypeError: Cannot read property '$router' of undefined
        at eval (Check.vue?a4ce:44)

Solution

  • Instead of:

    docRef.get().then(function (doc) {
    

    Use:

    docRef.get().then((doc) => {
    

    Explanation

    The this inside an arrow function body block refers to the current context, in your case, the Vue/component instance.

    But when you use function instead of an arrow function, the {} block creates a new context, changing the semantics of this, making it point to something else than the this outside that function.

    In other words, your problem happens because each function () {} has its own context (its own this), which could be set to something else. Arrow functions, OTOH, inherit the context (the this) of where it is declared. In this case, since you are declaring it inside a method, the this is the Vue instance. Using an arrow function keeps it. Using a function() does not guarantee it (the this could be set to something else, which generally is the case).

    For futher details, I recommend MDN - Arrow Functions.