自身の備忘録として残します。
postItem()が押下されたら「この内容で投稿しますか?」とアラートを表示させてif文で以下のように分岐してます。
「OK」の場合・・・Firestoreのpostsというコレクションを参照して保存。その後、「投稿しました」というアラートを表示し、
投稿が画面上でも確認できるようにrouter.goを使ってリロード実行。
「キャンセル」の場合・・・何も実行せず「キャンセルしました」というアラートを表示。
if文の後は.catch()でエラーを吐き出しております。
問題点
router.goを使わずに手動でリロードをしたら画面上に新しく追加した投稿が表示されるが、
router.goを使うとリロードは実行されるが、Firestoreにすら保存されず、画面表示もしない。
修正前のコード
postItem() {
const currentUser = firebase.auth().currentUser;
this.uid = currentUser.uid;
const id = firebase
.firestore()
.collection("posts")
.doc().id;
this.$swal({
title: "内容確認",
text: "この内容で投稿しますか?",
icon: "info",
buttons: true,
dangerMode: true,
})
.then((willDelete) => {
if (willDelete) {
firebase
.firestore()
.collection("posts")
.add({
title: this.title,
description: this.description,
genre: this.genre,
time: firebase.firestore.FieldValue.serverTimestamp(),
//サーバ側で値設定
id: id,
//dataにデータを作ってないので、thisは付けなくてOK!
uid: this.$route.params.uid,
});
this.$swal("投稿しました。", {
icon: "success",
});
this.$router.go({ path: `/board/${this.uid}`, force: true });
} else {
this.$swal("キャンセルしました。");
}
})
.catch(() => {
this.$swal("投稿出来ませんでした。", {
icon: "error",
});
});
},
原因
router.goが先に実行されてFiresutoreに保存がされていなかった為、
.then()内にアラートとrouter.goの処理をいれることで改善されました。
修正後のコード
postItem() {
const currentUser = firebase.auth().currentUser;
this.uid = currentUser.uid;
const id = firebase
.firestore()
.collection("posts")
.doc().id;
this.$swal({
title: "内容確認",
text: "この内容で投稿しますか?",
icon: "info",
buttons: true,
dangerMode: true
})
.then(willDelete => {
if (willDelete) {
firebase
.firestore()
.collection("posts")
.add({
title: this.title,
description: this.description,
genre: this.genre,
time: firebase.firestore.FieldValue.serverTimestamp(),
id: id,
uid: this.$route.params.uid
})
.then(() => {
this.$swal("投稿しました。", {
icon: "success"
});
this.$router.go({ path: `/board/${this.uid}`, force: true });
})
.catch(() => {
console.log("err");
});
} else {
this.$swal("キャンセルしました。");
}
})
.catch(() => {
this.$swal("投稿出来ませんでした。", {
icon: "error"
});
});
},
おまけ
以下の場合、コンソール内の「a」と「b」どちらが先に実行されるか。
答えは、「b」
Firebaseは外部から通信しているので、通信に多少たりとも時間を要する。
非同期では、アラート等の表示は先にするが、通信が必要な部分は後回しで
例の場合、先に「b」が実行されてから「a」が実行される為
したがって、修正前では先にリロードが実行されFirestoreに保存されなかった。
test() {
this.$swal({
title: "内容確認",
text: "この内容で投稿しますか?",
icon: "info",
buttons: true,
dangerMode: true
})
.then(() => {
if () {
firebase
.firestore()
.collection("test")
.add({
a:a
b:b
c:c
})
.then(() => {
/// console.log("a")
});
.catch(() => {});
} else {
this.$swal("キャンセルしました。");
}
})
/// console.log("b")
.catch(() => {});
});
},