Sonia
Sonia

Reputation: 195

Close Vuetify dialog with Vuex

After hours of searching and trying to find the correct method my n00b brain exploded. I've tried so many things that I'm complete lost. Everything works like I want it to, can remove the customer I want, the front refreshes etc. Except the dialog.

Can you please explain how to close this dialog?

Here is my dialog.

<template>
  <div>
    <template>
      <tbody>
        <tr v-for="customer in AllCustomers" :key="customer.id" class="todo">
          <td>{{customer.ID}}</td>
          <td>{{ customer.name }}</td>
          <td>{{customer.telephone}}</td>
          <td>{{customer.email}}</td>
          <v-btn color="success" @click="showDeleteDialog(customer)">DELETE</v-btn>
        </tr>
      </tbody>
    </template>
    <v-dialog v-model="dialogDelete" persistent max-width="500px">
      <v-card>
        <v-card-title>Delete</v-card-title>
        <v-card-text>Weet je zeker dat je {{customerToDelete}} wenst te verwijderen?</v-card-text>
        <v-card-actions>
          <v-btn color="primary" text @click="close">Annuleer</v-btn>
          <v-btn color="primary" text @click="deleteCustomer(customer.ID)">Verwijderen</v-btn>
        </v-card-actions>
      </v-card>
    </v-dialog>
  </div>
</template>



<script>
import { mapGetters, mapActions, mapState } from "vuex";

export default {
  name: "AllCustomers",

  data() {
    return {
      customerToDelete: "",
      dialogDelete: false
    };
  },

  methods: {
    ...mapActions(["fetchAllCustomers", "deleteCustomer"]),

    async close() {
      this.dialogDelete = false;
    },

    async showDeleteDialog(customer) {
      this.customer = Object.assign({}, customer);
      this.customerToDelete = this.customer.name;
      this.dialogDelete = !this.dialogDelete;
      this.$store.commit("toggleDialog");
    }
  },

  computed: mapGetters(["AllCustomers"]),
  created() {
    this.fetchAllCustomers();
  },
  ...mapState(["dialogDelete"])
};
</script>

And here my module js.

import axios from 'axios';

const state = {
    customers: [],
    dialogDelete: false
};

const getters = {
    AllCustomers: state => state.customers
};

const actions = {
    async fetchAllCustomers({ commit }) {
        const response = await axios.get(
            'http://localhost:8888'
        );
        console.log(response.data.data);
        commit('setAllCustomers', response.data.data);
    },

    async deleteCustomer({ commit }, id) {
        await axios.delete(`http://localhost:8888/delete`, {
            data: {
                id: id
            }
        })
        console.log(id)
        commit('removeCustomer', id, this.dialogDelete = false);
    },

}

const mutations = {
    setAllCustomers: (state, customers) => (state.customers = customers),
    removeCustomer: (state, id) =>
        (state.customers = state.customers.filter(customer => customer.ID !== id)),
}

export default {
    state,
    getters,
    actions,
    mutations
};

Upvotes: 0

Views: 1854

Answers (2)

Sameh
Sameh

Reputation: 736

Since you didn't include the <script> tag in your code, I'm assuming that you're trying to toggle the vuex state directly by your close event from the vue component, which wouldn't work this way. Instead, you would want to dispatch an action that commits a mutation that toggles the vuex state.

However, a better idea is to encapsulate the dialog component in a separate vue SFC (single file component) that has a local stateisActive, which you can toggle on or off via a local method this.isActive = false, and once you import that component you then give it a ref ref="deleteDialog", you'll then be able to access the component's internal methods like this: this.$refs.deleteDialog.close()

For more info about refs, see the docs.

EDIT

So for example:

DialogDelete.vue

<template>
    <v-dialog v-model="isActive" persistent max-width="500px">
      <v-card>
        <v-card-title>Delete</v-card-title>
        <v-card-text>Weet je zeker dat je {{customerToDelete}} wenst te verwijderen?</v-card-text>
        <v-card-actions>
          <v-btn color="primary" text @click="close">Annuleer</v-btn>
          <v-btn color="primary" text @click="deleteCustomer(customer.ID)">Verwijderen</v-btn>
        </v-card-actions>
      </v-card>
    </v-dialog>
</template>

<script>
  export default {
    data() {
      return {
        isActive: false
      }
    },
    methods: {
      close() {
        this.isActive = false
      },
      open() {
        this.isActive = true
      }
    },
  }
</script>

Parent.vue

<template>
  <div>
    <v-btn @click="openDialog">Open Dialog</v-btn>
    <dialog-delete ref="deleteDialog" />
  </div>
</template>

<script>
  export default {
    components: {
      dialogDelete: () => import("./DialogDelete.vue"),
    },

    methods: {
      openDialog() {
        this.$refs.deleteDialog.open()
      }
    },
  }
</script>

It's also clear to me that you're not placing the vuex helper methods (like mapGetters & mapState) where they should be, for example both of mapState & mapGetters should be within the computed:

computed: {
  ...mapGetters(["getterName"]),
  ...mapState(["stateName"])
}

check out the vuex docs.

Upvotes: 0

Rikkas
Rikkas

Reputation: 582

You should use mapState to get your dialogDelete variable from store:

 // in your dialog
 import { mapState } from "vuex"

 computed: {
 ...mapState(["dialogDelete"])
 }

and you should change its state in mutations with a commit:

// in vuex store
const mutations = {
setAllCustomers: (state, customers) => (state.customers = customers),
removeCustomer: (state, id) =>
    (state.customers = state.customers.filter(customer => customer.ID !== 
id)),
toggleDialog: (state) => (state.dialogDelete = !state.dialogDelete)    
}

// in your dialog
this.$store.commit("toggleDialog")

Upvotes: 1

Related Questions