0
votes

I have a couple of methods in my component that i would like to move into my Vuex Store to use them as Mutations/Actions but i am not quite sure how i would do it since they both are methods and i am calling one method in another and i know i cannot do that with a Mutation i.e. Call one mutation in another. I tried setting up an action and calling my mutation but i am getting an error.

Check out this working Codepen that has the methods set up that i want to move into Vuex.

And this is the working CodeSandbox with vuex implementation of the above.

Here is the working example that i want to move into my Vuex Store which is the same as the Codepen above:-

new Vue({
  el: "#app",
  data() {
    return {
      selected: [],
      animalList: [],
      moreAnimals: [{
          title: "cat",
          value: "cat"
        },
        {
          title: "Dog",
          value: "dog"
        },
        {
          title: "camel",
          value: "camel"
        },
      ]
    };
  },
  methods: {
    createTitle() {
      for (let i = 0; i < this.selected.length; i++) {
        let currentSelected = Object.assign({}, this.selected[i]);
        if (currentSelected.title != "camel")
          currentSelected.value = this.getAnimalName(currentSelected.title);
        this.animalList.push(currentSelected);
      }
      this.selected = [];
    },
    getAnimalName(title) {
      let lastAnimal = null;
      for (let i = 0; i < this.animalList.length; i++)
        if (this.animalList[i].title == title)
          lastAnimal = this.animalList[i];
      let index = (lastAnimal) ? Number(lastAnimal.value.split(" ")[1]) + 1 : 1;
      return title + ' ' + index;
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.min.js"></script>
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.min.css" rel="stylesheet" />

<div id="app">
  <v-app id="inspire">
    <v-container>
      <v-layout row wrap>
        <v-flex xs2 v-for="(animal,index) in animalList" :key="`${animal.value} - ${index}`">
          {{animal.value}}
        </v-flex>
      </v-layout>
      <v-flex v-for="(more,index) in moreAnimals" :key="`${more.value} - ${index}`">
        <v-checkbox :value="more" v-model="selected" :label="more.title">
        </v-checkbox>
      </v-flex>
      <v-btn @click="createTitle">Add</v-btn>
    </v-container>
  </v-app>
</div>

Basically i am trying to implement the above logic using Vuex. Any help will be appreciated. Thank you so much.

1

1 Answers

1
votes

Just turn getAnimalName into a getter:

getters: {
  // ...
  getAnimalName: (state) => (title) => {
      let lastAnimal = null;
      for (let i = 0; i < state.animalList.length; i++)
        if (state.animalList[i].title === title)
          lastAnimal = state.animalList[i];
      let index = lastAnimal ? Number(lastAnimal.value.split(" ")[1]) + 1 : 1;
      return title + " " + index;
  }
},
mutations: {
  setSelected(state, payload) {
    state.selected = payload;
  }.
  addToList(state, animal) {
    state.animalList.push(animal)
  }
},
actions: {
    createTitle({ commit, state, getters }) {
      for (let i = 0; i < state.selected.length; i++) {
        let currentSelected = Object.assign({}, state.selected[i]);
        if (currentSelected.title !== "camel")
          currentSelected.value = getters.getAnimalName(currentSelected.title);
        commit('addToList', currentSelected);
      }
      commit('setSelected', []);
    }
  }