Jorje12
Jorje12

Reputation: 423

How to add object to array using Vuex?

I am trying to make a Todo List using Vuejs and Vuex.
I am using Vue CLI.

This is the store:

import Vue from 'vue';
import Vuex from 'vuex';
import todoList from "./modules/todoList"

Vue.use(Vuex);

export default new Vuex.Store({
    modules: {
        todoList
    }
})

This is the module store:

const state = {
  todoList: [
    {
      id: 1,
      title: "Todo One",
    },
    {
      id: 2,
      title: "Todo Two",
    },
  ],
};

const getters = {
  getTodoList: (state) => state.todoList,
};

const actions = {
  addTask({ commit }, task) {
    commit("ADD_TASK", task);
    task.title = "";
  },
};
const mutations = {
  ADD_TASK(state, task) {
    state.todoList.push({
        id: task.id,
        title: task.title
    });

  },
};

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


This is the Todo Container that is used in App.vue and acts as a parent element for Todo :

<template>
  <section>
    <h2>Todo List</h2>
    <input type="checkbox" v-model="showDoneTasks" name="" id="" />
    <Todo />
    <div>
      <input
        type="text"
        name="enterTodo"
        placeholder="What are you up today ?"
        v-model="task.title"
      />
      <button @click="addTask">
        <i class="fas fa-plus"></i>
      </button>
    </div>
  </section>
</template>

<script>
import Todo from "./Todo.vue";
import { mapActions } from "vuex";

export default {
  name: "TodoContainer",
  components: {
    Todo,
  },
  data: () => {
    return {
      task: {
        id: 0,
        title: ""
      },
      checkBox: false,
    };
  },
  methods: {
    ...mapActions({
      addTask: 'addTask',
    }),
    removeTask() {},
    editTask() {},
    completeTask() {},
    showDoneTasks() {
      this.checkBox = !this.checkBox;
    },
  },
  computed: {},
};
</script>

<style scoped></style>

This is Todo, the child element:

<template>
  <div>
    <div class="todo" v-for="todo in getTodoList" :key="todo.id">
      {{ todo.title }}
    </div>
  </div>
</template>

<script>
import { mapGetters } from "vuex";

export default {
  name: "Todo",
  computed: {
    ...mapGetters(["getTodoList"]),
  },
};
</script>

<style scoped></style>

By using the Vue Devtools I can see that there are objected being pushed into the array, but their id and title is undefined.

I am a total beginner in Vuejs and Vuex. I can't figure out the problem even while reading the vue documenation: https://vuex.vuejs.org/guide/actions.html

I have posted here because I couldn't find anything regarding my problem in over 6 hours. I am hopeless.

Upvotes: 1

Views: 1087

Answers (1)

Manoj
Manoj

Reputation: 841

Working example for addTask ,deleteTask(other functions can be added accordingly).

https://vuex-todos-jorje.netlify.app/

code- https://github.com/manojkmishra/vuex_todos_jorje

store.js

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)

export default new Vuex.Store({
state: {todoList: [  ],  },
getters: { getTodoList: (state) => state.todoList,  },
mutations: {
ADD_TASK(state, title) {
  if (state.todoList.map(todoList => todoList.title).indexOf(title) === -1)    
 { state.todoList.push({ title})
  }
},
DELETE_TASK(state, title) {
state.todoList.splice(state.todoList.indexOf(title), 1)
},
},
actions: {
addTask({ commit }, task) {  
  commit("ADD_TASK", task.title);
},
deleteTask({ commit }, title) {
   commit("DELETE_TASK", title)
},
},
 modules: {  }
})

Todos.vue [container component]

<template>
<div class="App">
<div class="App__box">
  <Todo v-for="(todo, index) in todos"
    :key="index" :text="todo.title" @delete="deleteTask(todo)"
  ></Todo>
</div>
<div>
  <input  class="inp" type="text" name="enterTodo" 
    placeholder="What are  you up today ?"
    v-model="task.title"/>
  <button @click="addTask">Add </button>
</div>
</div>
</template>
<script>
import Todo from './Todo'
import { mapActions } from 'vuex'
export default {
name: 'App',
components: {Todo },
data () {  return { task: {  id: '', title: ''  }, }  },
computed: {
  todos () { console.log('store',this.$store.state)
     return this.$store.state.todoList},
},
methods: {
  ...mapActions([ 'deleteTask',]),
  addTask (e) { if (this.task) { this.$store.dispatch('addTask', this.task);
  this.task.title='' }  },
}
}
</script>
<style scoped>
i{padding:5px}
.App__box{
 padding-bottom:30px;
}
</style>

Todo.js [child component]

<template>
<div class="todo" >
 {{ text }}
 <button  @click="$emit('delete')" >del</button>
</div>
</template>
<script>
import { mapGetters } from "vuex";
export default {
name: "Todo",
props: {  text: { type: String, default: '',  },  },
};
</script>
<style scoped>
.todo{
padding-top:10px;
padding-bottom:10px;
}
</style>

Upvotes: 1

Related Questions