web-dev-qa-db-fra.com

ne peut pas lire la propriété 'dispatch' de undefined dans Vuex

J'essaie d'effectuer un envoi sur 'logOutUser' dans le magasin Vuex et j'obtiens le message d'erreur suivant dans Respone:

TypeError: Impossible de lire la propriété 'dispatch' de non définie

deleteUser.vue (le composant à partir duquel l'action de répartition ne fonctionne pas):

<template>
    <v-dialog v-model="openDelete" persistent max-width="500px">
        <v-card>
            <v-card-title>
                <h4>Delete User</h4>
            </v-card-title> 
            <v-card-text>
                <h2>Are You Sure?</h2>
                <p>Deleting your user is a permanent action.</p>
                <br>
                <br>
                <v-btn
                 color="primary"
                 @click="deleteUser">
                 Delete User
                </v-btn>
                <v-btn
                 color="primary"
                 @click="openDelete = false">
                 Close
                </v-btn>  
            </v-card-text>  
        </v-card>   
    </v-dialog> 
</template>
<script>
import router from '../../router/index.js'
const firebase = require('../../firebaseConfig.js')
export default {
    data: function(){
        return {
            openDelete: true
        }
    },
    methods: {
        deleteUser: function(){
            let user = firebase.auth.currentUser
            const docId = user.uid
            console.log("Trying to delete user ", docId)
            user.delete().then(function() {
            }).catch(function(error) {
                console.error("Error deleting user: ", error)
            });
            firebase.firestore.collection("users").doc(docId).delete().then(() => {
                        console.log('Trying to Log Out in Vuex')
                        this.$store.dispatch('user/logOutUser')
                        alert("User Deleted Successfully!")
                }).catch(function(error) {
                    console.error("Error removing document: ", error);
                });
            router.Push('hello')    
            this.openDelete = false
        }
    }
}
</script>

store.js:

import Vue from 'vue'
import Vuex from 'vuex'
import user from './modules/user'
import genre from './modules/genre'

Vue.use(Vuex)

export default new Vuex.Store({
    modules: {
        user,
        genre
    }
})

user.js:

const firebase=require('../firebaseConfig.js')

const state = {
    currentUser: null,
    userProfile: {}
}

const actions = {
        fetchUserProfile({commit, state}, uid){
            firebase.firestore.collection("users").doc(uid).get().then((doc)=>{
                commit('setUserProfile', doc.data())
            }).catch((error)=>{
                console.error(error)
            })
        },
        logOutUser({commit, state}){
            commit('setCurrentUser', null)
            commit('setUserProfile', {})
            console.log('Logged Out In Vuex')
        }
}

const mutations = 
    {
        setCurrentUser(state, val){
            state.currentUser = val
        },
        setUserProfile(state, val){
            state.userProfile = val
        }
    }

export default {
    namespaced: true,
    state,
    actions,
    mutations
}   

EDIT: Voici mon fichier main.js:

import Vue from 'vue'
import App from './App'
import router from './router'
import store from './store.js'
const firebase = require('./firebaseConfig.js')

Vue.config.productionTip = false

let app

firebase.auth.onAuthStateChanged(user => {
  if(!app){
    /* eslint-disable no-new */
    app = new Vue({
      el: '#app',
      router,
      store,
      components: { App },
      template: '<App/>'
    })
  }
});

Je dois mentionner que j'envoie cette action à partir d'un autre composant de ma candidature et que cela fonctionne parfaitement à partir de là.

Je vous remercie!

2
Tom Harpaz

En effet, vous n'avez probablement pas ajouté l'option store à l'instance racine de Vue. En le fournissant, vous pourrez accéder au magasin à partir de tous les composants enfants de root. Par conséquent, votre instance racine devrait ressembler à ceci:

import store from './store'

const app = new Vue({
  /* .. other properties .. */
  store
})

Vous pouvez maintenant utiliser librement this.$store dans vos composants.

3
Konrad Kalemba

J'ai donc essayé toutes vos solutions et rien ne semble fonctionner pour moi. J'ai commencé à soupçonner que le problème est lié au fait que deleteUser.vue n'est pas un enfant direct d'App.vue. Quiconque que j'ai finalement importé stocke directement dans le composant:

import store from '../../store.js'

Il a résolu le problème . Je me demande si quelqu'un connaît un moyen plus efficace de résoudre ce problème. Merci pour votre aide!

0
Tom Harpaz

Si nous allons suivre la structure d'application suggérée par vueX.

Store sera injecté automatiquement

https://vuex.vuejs.org/guide/structure.html

0
Mukundhan

Mon hypothèse serait soit le magasin non initialisé, soit le mauvais contexte this.

Pour les besoins du débogage, j'essaierais d'utiliser mapActions helper vuex.vuejs.org :

import { mapActions } from 'vuex'

export default {
  methods: {
    ...mapActions({
      add: 'increment' // map `this.add()` to `this.$store.dispatch('increment')`
    })

    // ...
  }

  // ...
}
0
bruddha