1
votes

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.

2

2 Answers

2
votes

This means that the data property of response is not defined.

Is the AuthenticationService.register method asynchronous?

I'd imagine it is. If so, your code is continuing before the response object has been properly resolved.

Take a second and run console.log(response). You may see an unresolved promise if the method is async.

Otherwise, you may see nothing defined at all if the method does not return anything but instead uses callbacks.

2
votes

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'
        })
      });
    }