Search code examples
vue.jsvuejs2vuex

TypeError: Cannot read property 'token' of undefined store dispatch vuex


I have a vue component that makes use of the store Vuex. However I get a

TypeError: Cannot read property 'token' of undefined

error. I don't understand why. This is my code:

In main.js:

import Vue from 'vue'
import Vuex from 'vuex';
import App from './App.vue'
import router from './router';
 import "./assets/css/tailwind.css";
import '@/assets/css/tailwind.css';
import store from './store';

Vue.config.productionTip = false;

 Vue.use(Vuex);

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

In store/indes.js:

import Vue from 'vue';
import Vuex from 'vuex';

 
Vue.use(Vuex);

export default new Vuex.Store({
    modules: {
    },
    state:  {
        token: ''
    }
})

In GenericForm.vue:

  methods:  {
    execute()  {
      console.log("GenericForm.vue")

      if (this.inputFunction)  {
        this.inputFunction()
      }

      this.register()
    },

      register () {
      console.log("register()")
      try {
        const response =   AuthenticationService.register({
          email: 'testss',
          password: 'frgr'
        })
           this.$store.dispatch('setToken', response.data.token)
           this.$store.dispatch('setUser', response.data.user)
           this.$store.router.push({
          name: 'songs'
        })
      } catch (error) {
        console.log(error)
/*
        this.error = error.response.data.error
*/
      }
    }
  }

enter image description here

the error occurs on this line of code:

 this.$store.dispatch

Any help is appreciated.

EDIT:

AuthenticationService.js

import api from './api'

export default  {
    register (credentials)  {
        return api().post('register', credentials)
    }
}

api.js

import axios from 'axios'

export default()  =>  {
    return axios.create({
        baseURL: 'http://localhost:8081'
    })
};

After adding console.log: enter image description here

EDIT2:

New method:

    register: async () => {

     
      console.log("register()")
      const response = AuthenticationService.register({
        email: 'testss',
        password: 'frgr'
      }).then((response) => {

        console.log(response)
       /* this.$store.dispatch('setToken', response.data.token)
        this.$store.dispatch('setUser', response.data.user)*/
        this.$store.router.push({
          name: '/test'
        })
      });
    }

I get the error on

 this.$store.router.push({
          name: '/test'
        })

line:

enter image description here

The response gets logged alright, though.


Solution

  • There are two problems:

    First problem:

    This code:

    register(credentials)  {
        return api().post('register', credentials)
    }
    

    is returning a Promise, which has no data property. What you want is to access the axios response wrapped in that promise, so you either:

    • call then on the promise
    AuthenticationService.register({...}).then((response) => {
        console.log(response.data.token) // 'foo'
    });
    
    • use async/await inside the Vue component

    Second problem

    The problem that causes the store to be undefined, is the use of the arrow functions. The register() method shouldn't have an arrow. Once the arrow gets removed there is no error (store is defined, as well as a router):

        async register() {
          console.log("register()")
          const response = AuthenticationService.register({
            email: 'testss',
            password: 'frgr'
          }).then((response) => {
    
            console.log(response)
            console.log(this.$store)
            this.$router.push({
              name: 'ha'
            })
          });
        }