I am currently developing a todo list application using Vue.js, Vuex, and Firebase. The functionality of the app seems to be in working order with the Store file effectively managing the retrieval and display of entered todo items to and from Firestore. However, I have encountered a query regarding the configuration of parameters in Vuex. The REMOVE_TODO function within mutations (refer to store.js) seems to expect two arguments, even though only the "id" argument is utilized in the actual function's code. Removing the initial argument (in this case, "state") triggers an error message in the console stating: "Function CollectionReference.doc() requires its first argument to be of type non-empty string, but it was: a custom Object object". My question pertains to why the REMOVE_TODO function necessitates two arguments to function correctly when only the "id" parameter is utilized in the function. Why is the presence of the additional argument essential? The relevant sections of my code are provided below for reference. Thank you!
app.vue
<template>
<div id="app" class="container">
<input class="form-control" :value="newTodo" @change="getTodo" placeholder="I need to...">
<button class="btn btn-primary" @click="addTodo">Add New Post</button>
<ul class="list-group">
<li class="list-group-item" v-for="todo in this.$store.getters.getTodos" :key="todo.id">
{{todo.title}}
<div class="btn-group">
<button type="button" @click="remove(todo.id)" class="btn btn-default btn-sm">
<span class="glyphicon glyphicon-remove-circle"></span> Remove
</button>
</div>
</li>
</ul>
</div>
</template>
<script>
export default {
beforeCreate: function() {
this.$store.dispatch('setTodo')
},
methods: {
getTodo(event) {
this.$store.dispatch('getTodo', event.target.value)
},
addTodo() {
this.$store.dispatch('addTodo')
this.$store.dispatch('clearTodo')
},
remove(id){
this.$store.dispatch('removeTodo', id)
}
},
computed: {
newTodo() {
return this.$store.getters.newTodo
},
todos(){
return this.$store.getters.todos
}
}
}
</script>
<style>
body {
font-family: Helvetica, sans-serif;
}
li {
margin: 10px;
}
</style>
store.js
import Vue from 'vue'
import Vuex from 'vuex'
import db from '../firebase'
Vue.use(Vuex);
export default new Vuex.Store({
state: {
todos: [],
newTodo: '',
errors: ''
},
mutations: { //syncronous, committed
GET_TODO: (state, todo) => {
state.newTodo = todo
},
ADD_TODO: state => {
db.collection('items').add({
title: state.newTodo,
created_at: Date.now(),
}).then(function(){
console.log('Document successfully added')
})
.catch((error) => {
this.errors = error
})
},
REMOVE_TODO: (state, id) => {
if (id) {
db.collection("items").doc(id).delete().then(function() {
console.log('Document successfully deleted')
})
.catch((error) => {
this.errors = error
})
} else {
this.errors = 'Invalid ID'
}
},
CLEAR_TODO: state => {
state.newTodo = ''
},
SET_TODO: state => {
let todos = []
db.collection('items').orderBy('created_at').onSnapshot((snapshot) => {
todos = []
snapshot.forEach((doc) => {
todos.push({ id: doc.id, title: doc.data().title })
})
state.todos = todos
})
}
},
actions: { //asyncronous, dispatched
getTodo: (context, todo) => {
context.commit('GET_TODO', todo)
},
addTodo: context => {
context.commit('ADD_TODO')
},
removeTodo: (context, id) => {
context.commit('REMOVE_TODO', id)
},
clearTodo: context => {
context.commit('CLEAR_TODO')
},
setTodo: context => {
context.commit('SET_TODO')
}
},
getters: {
newTodo: state => state.newTodo,
getTodos: state => {
return state.todos
}
}
})