Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Update data using vuex

As Vuex, I'm trying to update an object using form. My code like this.

In store:

const state = {
   categories: []
};

//mutations:
[mutationType.UPDATE_CATEGORY] (state, id, category) {
    const record = state.categories.find(element => element.id === id);
    state.categories[record] = category;
}

//actions:
updateCategory({commit}, id, category) {
  categoriesApi.updateCategory(id, category).then((response) => {
    commit(mutationType.UPDATE_CATEGORY, id, response);
    router.push({name: 'categories'});
  })
}

Template in .Vue file:

    <form>
      <div class="form-group">
        <label for="Name">Name</label>
        <input
          type="text"
          class="form-control form-control-sm"
          name="name"
          v-model.lazy="category.name" required>
      </div>

      <div class="form-group">
        <label for="Slug">Slug</label>
        <input
          type="text"
          class="form-control form-control-sm"
          name="slug"
          v-model.lazy="category.slug" required>
      </div>

      <div class="form-group">
        <label for="Avatar">Avatar</label>
        <input
          type="text"
          class="form-control form-control-sm"
          name="avatar"
          v-model.lazy="category.avatar" required>
      </div>

      <div class="form-group">
        <label for="Description">Description</label>
        <textarea
          type="text"
          class="form-control form-control-sm"
          rows="5"
          name="description"
          v-model.lazy="category.description"></textarea>
      </div>

      <div class="form-group">
        <button type="submit" @click.prevent="updateCategory" class="btn btn-outline btn-sm">Update</button>
      </div>

    </form>

And in script:

export default {
    data() {
      return {
        category: {}
      }
    },

    methods: {
      getCategoryById(id) {
        axios.get(`categories/${id}`)
          .then(response => {
            this.category = response.data;
          })
          .catch(error => {
            console.log(error);
          })
      },

      // Using mutation.
      updateCategory() {
        this.$store.dispatch('updateCategory', this.$route.params.id, this.category);
        console.log(this.category); //Display exactly data changed.
      }
    },

    created() {
      this.getCategoryById(this.$route.params.id);
    }
}

My problem is when I click Update. It nothing change. I did print category Object in console. It displays exactly what I expected. But after click Update button. It hasn't changed.

Anyone can tell me why and give me solution?? Thanks.

like image 581
Thuan Nguyen Avatar asked May 18 '18 16:05

Thuan Nguyen


People also ask

How do I update my Vuex data?

To update existing data, you can do so with the update method. Following example is some simple Vue Component handling data update with form data. The update method takes where condition and data as payload. where condition can be a Number or a String representing the value of the primary key of the Model.

Does Vuex keep state on refresh?

To persist Vuex state on page refresh, we can use the vuex-persistedstate package. import { Store } from "vuex"; import createPersistedState from "vuex-persistedstate"; import * as Cookies from "js-cookie"; const store = new Store({ // ...

How does Vuex store data?

js inside the store folder created by vue itself and add the necessary functionality there: import Vue from "vue"; import Vuex from "vuex"; Vue. use(Vuex); export default new Vuex. Store({ state: { data: null }, mutations: { getData(state, newData) { state.

What is the use of mapState in Vuex?

Mapping State Vuex provides a helper function called mapState to solve this problem. It is used for mapping state properties in the store to computed properties in our components. The mapState helper function returns an object which contains the state in the store.


2 Answers

You can wrap your parameters in 1 payload object:

In your component

this.$store.dispatch('updateCategory', {
  id: this.$route.params.id,
  data: this.category
});

in your store, you need to made new object when edit categories array (you can read more about immutable)

const state = {
   categories: []
};

//mutations:
[mutationType.UPDATE_CATEGORY] (state, payload) {
    state.categories = state.categories.map(category => {
      if (category.id === payload.id) {
        return Object.assign({}, category, payload.data)
      }
      return category
    })
}

//actions:
updateCategory({commit}, payload) {
  categoriesApi.updateCategory(payload.id, payload.data).then((response) => {
    commit(mutationType.UPDATE_CATEGORY, payload);
    router.push({name: 'categories'});
  })
}
like image 100
ittus Avatar answered Sep 29 '22 10:09

ittus


and much more simple, just use methods to modify arrays (never modify them directly) (check this: https://vuejs.org/2016/02/06/common-gotchas/#Why-isn%E2%80%99t-the-DOM-updating even old and DOM related, is still valid)

So just find your object and replace with splice in your mutation:

const index = state.objectsArray.map(o => o.id).indexOf(newObject.id);
state.objectsArray.splice(index, 1, newObject);
like image 35
estani Avatar answered Sep 29 '22 09:09

estani