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?
Answer
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 );