0

I have the following Vue.js app structure (src directory):

.
├── App.vue
├── assets
├── data
│   ├── config.js
├── main.js
├── router.js
└── views
    └── app
        ├── index.vue
        ├── main
        │   ├── dashboard.vue
        │   └── index.vue
        ├── sessions
        │   ├── index.vue
        │   ├── login.vue

I already have implemented Firebase authentication, which works fine (refering to data/config.js). In my login.vue, I have the login form and a submit button:

<b-form @submit.prevent="formSubmit">
...
<b-button
   type="submit"
...

which executes the formSubmit method:

<script>
...
  methods: {
    formSubmit() {

      firebase
        .auth()
        .signInWithEmailAndPassword(this.email, this.password)
        .then(data => {
          this.$router.push('/app/main/dashboard').catch((err) => {
            throw new Error(`${err}`);
          });
        })
        
        .catch(err => {
          console.log("not successful")
          this.error = err.message;
          alert(err.message);
        });

    },
  },
...
</script>

As said, authentication works, I just don't get the redirect to the start page when successfully authenticated to work. Using the code above, I get

Uncaught (in promise) Error: undefined

in the browser inspector. I assume this has something to do with the this statement, but I'm running out of ideas how I can rewrite this to get a successful redirect. Does anybody has a hint for me?

Thanks!

dom_weissb03
  • 415
  • 2
  • 5
  • 8

2 Answers2

0

I think you should be fine like this:

<script>
...
  methods: {
      firebase
        .auth()
        .signInWithEmailAndPassword(this.email, this.password)
        .then(data => {
          this.$router.push('/app/main/dashboard');
        })
        .catch(err => {
          console.log("not successful")
          this.error = err.message;
          alert(err.message);
        });
}
...
</script>

You can't call catch on this.$router.push. You could maybe wrap it in a try and catch block:

try {
  this.$router.push('/app/main/dashboard');
} catch (error) {
  console.log(error) 
}

But I doubt it would make much sense as the route will be changed if it's available or not. I would suggest creating a fallback error page. Like mentioned here.

Vuex approach:

Create an index.js file inside the store folder.

import * as firebase from 'firebase'; 

   export const state = () => ({})
    
    export const actions = {
       signInWithEmailAndPassword({ commit, dispatch }, payload) {
        return firebase
        .auth()
        .signInWithEmailAndPassword(payload.email, payload.password)
        .then(data => {
          return Promise.resolve(data);
        })
        .catch(err => {
          console.log("not successful")
          this.error = err.message;
          return Promise.reject(err);
        });
       }
    }

and then in your form component:

    <script>
...
  methods: {
    formSubmit() {
      this.$store.dispatch("signInWithEmailAndPassword", { email: this.email, password: this.password } )
      .then(data => {
          this.$router.push('/app/main/dashboard');
      });
    }
  }, ...
</script>
dummker
  • 315
  • 1
  • 13
  • Thanks for that, unfortunately I still get the error above. Since I still assume that this has to be something to do with **this**, is there a way to avoid that and call the router with something else? – dom_weissb03 Jul 14 '20 at 06:35
  • Weird. You could try to form the authentication logic inside of a vuex store, call the desired action method and then in the promise handle the redirect. Will edit my answer. – dummker Jul 14 '20 at 08:13
  • Hm, strange. Now I get `[vuex] unknown action type: signInWithEmailAndPassword`. Do I have to refer / import the store/index.js somehow? – dom_weissb03 Jul 14 '20 at 12:11
  • if you call the store file `index.js` it should be recognized – dummker Jul 14 '20 at 18:26
0

For some reason I don't get it to work. I now have put the signInWithEmailAndPassword into the export default new Vuex.Store in store/index.js:

// Create store
export default new Vuex.Store({
  modules: {
    largeSidebar,
    compactSidebar,
    chat,
    config,
    authData,
    invoice,
    cart,
    verticalSidebar,
    scrumboard
  },
  actions: {
    signInWithEmailAndPassword({ commit, dispatch }, payload) {
      return firebase
      .auth()
      .signInWithEmailAndPassword(payload.email, payload.password)
      .then(data => {
        return Promise.resolve(data);
      })
      .catch(err => {
        console.log("not successful")
        this.error = err.message;
        return Promise.reject(err);
      });
    }


  }
});

but again get vue-router.esm.js?8c4f:2089 Uncaught (in promise) undefined

dom_weissb03
  • 415
  • 2
  • 5
  • 8