How to acces Vue.prototype inside an .addEventListener?

I’m trying to access global object of Vue.prototype.$firebase which is declared in main.js

import Vue from "vue";
import App from "./App.vue";
import router from "./router";
import VueTailwind from "vue-tailwind";
import { FirebaseApp } from "@/firebase/firebase";
//Style
import "@/assets/styles/app.css";
import settings from "@/assets/styles/Tailwind.js";

FirebaseApp.auth().onAuthStateChanged((user)=>{
  Vue.prototype.$user = user;
})

//Vue
Vue.config.productionTip = false;
Vue.use(VueTailwind, settings);
Vue.prototype.$firebase = FirebaseApp;

new Vue({
  router,
  render: h => h(App)
}).$mount("#app");

inside of a Login component

<script>
export default {
  name: "Login",
  mounted: function () {
    this.submit();
  },
  methods: {
    submit() {
      let login = document.getElementById("login");     
      login.addEventListener(
        "submit",
        function (event) {
          event.preventDefault();
          const email = login.email.value;
          const password = login.password.value;
          this.$firebase
            .auth()
            .signInWithEmailAndPassword(email, password)
            .then((user) => {
              console.log(user)
              this.$router.replace('/')
            })
            .catch((error) => {
              console.log(error);
            });
        },
        true
      );
    },
  },
};
</script>

But i get TypeError: Cannot read property 'auth' of undefined, same with this.$router.
But instantiating the object outside the .addEvenListener prints well and gives me access through the let signIn, but it’s no the desire behavior i want, instead, i want to route "automatically" between a login and a dashboard on onAuthStateChange by doing the login with the Vue.prototype.$firebase instead of the local instantiation:

<script>
export default {
  name: "Login",
  mounted: function () {
    this.submit();
  },
  methods: {
    submit() {
      let login = document.getElementById("login");
      let signIn = this.$FirebaseApp;
      let onLogin = this.$router;
      login.addEventListener(
        "submit",
        function (event) {
          event.preventDefault();
          const email = login.email.value;
          const password = login.password.value;
          signIn
            .auth()
            .signInWithEmailAndPassword(email, password)
            .then((user) => {
              console.log(user)
              onLogin.replace('/')
            })
            .catch((error) => {
              console.log(error);
            });
        },
        true
      );
    },
  },
};
</script>

How is the correct way to access the Vue.prototype.$firebase and why it does have such scope limitation?

21 thoughts on “How to acces Vue.prototype inside an .addEventListener?”

  1. Avoid using function() inside component callbacks and use arrow functions instead.

    The function creates its own this context, so that this will no longer refer to the component, but arrow functions use the surrounding this context:

    login.addEventListener(
      "submit",
      (event) => {   // Changed to arrow function
      ...            // Now you can access `this.$firebase`
      },
      true
    );
    
    Reply

Leave a Comment