前提・実現したいこと
現在nuxtでTODOアプリを作成中です。DBはcloud firestoreを使用しています。
TODOを入力するtextの隣にプルダウンで月日が選択できるようになっています。
textに文字を入力し、月日を選択してTODOを追加ボタンを押すとそれがDBに保存されて尚且つ、
DOMに反映させるように実装したいのですがうまくいかずに悩んでいます。
ちなみに下記のエラーメッセージが表示されます。
発生している問題・エラーメッセージ
Function addDoc() called with invalid data. Unsupported field value: undefined (found in field month in document todos/8avIZCvau8utj6ttWYQ9)
無効なデータで関数 addDoc() が呼び出されました。サポートされていないフィールド値: 未定義 (ドキュメントの日付フィールドにあります)
翻訳するとこういう意味らしいです。
該当のソースコード
storeディレクトリのsampleディレクトリの中のindex.jsフォルダです
vuex
1import firebase from '~/plugins/firebase' 2import { firestoreAction } from 'vuexfire' 3 4const db = firebase.firestore() //データベースはfirebase.firestore 5const todosRef = db.collection('todos')//コレクション名はtodos 6 7export const state = () => ({ 8 todos: [], 9}) 10 11export const actions = { 12 init: firestoreAction(({ bindFirestoreRef })=>{ 13 bindFirestoreRef('todos', todosRef) 14 }), 15 add: firestoreAction((context, name, month, day) => { 16 if(name.trim()){ //入力値が空白ではないか確認 17 todosRef.add({ 18 name: name, 19 month: month, //ここです 20 day: day, //ここです 21 done: false, 22 created: firebase.firestore.FieldValue.serverTimestamp() 23 24 25 }) 26 } 27 }), 28 remove: firestoreAction((context, id) => { 29 todosRef.doc(id).delete() 30 }), 31 toggle: firestoreAction((context, todo) => { //todoの完了未完了 32 todosRef.doc(todo.id).update({ 33 done: !todo.done 34 }) 35 }), 36} 37 38export const getters = { 39 orderdTodos: state => { 40 return _.sortBy(state.todos, 'created') 41 //state.todosの値をcreatedでソートして返す、orderdTodosという名前でコンポーネントから呼び出す 42 } 43} 44
addが追加機能です。firestoreActionの引数に月はmonth、日はdayを入れています。
vuecomponents
1todos.vue 2 3<template> 4 <div app> 5 <div class="page"> 6 <ul> 7 <li v-for="todo in todos" :key="todo.id"> 8 <!-- todoのcreatedに値がある時だけspanで囲ったtodoの要素を描画 --> 9 <span v-if="todo.created"> 10 <button @click="remove(todo.id)">×</button> 11 <input 12 type="checkbox" 13 :checked="todo.done" 14 @change="toggle(todo)" 15 /> 16 <!-- firestote上のデータに基づいてチェックボックスのオンオフを切り替え --> 17 <!-- changeで選択肢が変更された時に発火する toggleメソッドを呼び出す --> 18 <span :class="{ done: todo.done }"> 19 <!-- doneの値がtrueだったらdoneクラスが設定される --> 20 {{ todo.name }} {{ todo.created.toDate() | dateFilter }} 21 {{ todo.month }}月{{ todo.day }}日 22 </span> 23 </span> 24 </li> 25 </ul> 26 <form @submit.prevent="add"> 27 <!-- addTodoを押したときにページがリロードされないようにする --> 28 <input v-model="name" type="text" placeholder="Todoを追加" /> 29 <!-- <input type="date" name="date" v-model="date" value="date" /> --> 30 <select name="month" size="1" v-model="month"> 31 <option value="" hidden>Month</option> 32 <option v-for="month in 12" :key="month" :value="month"> 33 {{ month }}月 34 </option> 35 </select> 36 <select name="day" size="1" v-model="day"> 37 <option value="" hidden>Day</option> 38 <option v-for="day in 31" :key="day" :value="day">{{ day }}日</option> 39 </select> 40 <button type="submit">Todoを追加</button> 41 </form> 42 </div> 43 </div> 44</template> 45 46<script> 47import moment from "moment"; 48export default { 49 created() { 50 this.$store.dispatch("sample/init"); 51 }, 52 data() { 53 return { 54 name: "", 55 month: "", 56 day: "", 57 done: false, 58 }; 59 }, 60 computed: { 61 todos() { 62 // return this.$store.state.sample.todos; 63 return this.$store.getters["sample/orderdTodos"]; 64 // vuexのsample/index.jsからリストを以降 65 //storeのstateのsample/index.jsの中のtodos 66 }, 67 user() { 68 return this.$store.getters["user"]; 69 }, 70 }, 71 filters: { 72 dateFilter(date) { 73 return moment(date).format("YYYY/MM/DD HH:mm:ss"); 74 }, 75 }, 76 methods: { 77 // ボタンを押したらTodoを追加 78 add() { 79 this.$store.dispatch("sample/add", this.name, this.month, this.day); 80 81 this.name = ""; 82 this.month = ""; 83 this.day = ""; 84 }, 85 86 // Todoの削除 87 remove(id) { 88 //idはfirestoreのドキュメントid 89 this.$store.dispatch("sample/remove", id); 90 }, 91 toggle(todo) { 92 this.$store.dispatch("sample/toggle", todo); 93 }, 94 }, 95}; 96</script> 97 98<style> 99li > span > span.done { 100 text-decoration: line-through; 101} 102</style> 103 104
試したこと
index.jsの
month:month
day:day
の値をそれぞれ''で囲んでstring型にすると反映されます。
只、表示はあくまでもそのまま文字列として表示されてしまいます。
もしわかりそうな方いらっしゃいましたらヒントでも良いので教えていただけるとありがたいです。
宜しくお願いします。
補足情報(FW/ツールのバージョンなど)
以下package.jsonより
"@nuxtjs/axios": "^5.12.2",
"@nuxtjs/dotenv": "^1.4.1",
"@nuxtjs/proxy": "^2.1.0",
"core-js": "^3.6.5",
"firebase": "^8.2.1",
"moment": "^2.29.1",
"nuxt": "^2.14.6",
"nuxt-webfontloader": "^1.1.0",
"vuex": "^3.6.0",
"vuexfire": "^3.2.5"
あなたの回答
tips
プレビュー