質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Vue.js

Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

Firebase

Firebaseは、Googleが提供するBasSサービスの一つ。リアルタイム通知可能、並びにアクセス制御ができるオブジェクトデータベース機能を備えます。さらに認証機能、アプリケーションのログ解析機能などの利用も可能です。

Cloud Firestore

Cloud Firestore は、自動スケーリングと高性能を実現し、アプリケーション開発を簡素化するように構築された NoSQLドキュメントデータベースです。

Q&A

解決済

1回答

5491閲覧

エラーコード: Error in render: "TypeError: Cannot read property 'uid' of undefined"を解消したい

TMTN

総合スコア52

Vue.js

Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

Firebase

Firebaseは、Googleが提供するBasSサービスの一つ。リアルタイム通知可能、並びにアクセス制御ができるオブジェクトデータベース機能を備えます。さらに認証機能、アプリケーションのログ解析機能などの利用も可能です。

Cloud Firestore

Cloud Firestore は、自動スケーリングと高性能を実現し、アプリケーション開発を簡素化するように構築された NoSQLドキュメントデータベースです。

0グッド

0クリップ

投稿2021/06/12 10:37

編集2021/06/13 21:23

イメージ説明

上記より2つエラーが出ている状況です。

#1つ目

[Vue warn]: Property or method "uid" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property. See: https://vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.

こちらにつきましては、エラーコード内にあるURLを確認すると反応性の宣言と以下のように書かれておりました。


Vue はルート レベルのリアクティブ プロパティを動的に追加することを許可していないため、空の値であっても、すべてのルート レベルのリアクティブ データ プロパティを事前に宣言して、Vue インスタンスを初期化する必要があります。


その為、以下のようにdata()内にuid=""という風に初期化させました。

export default { components: { Nl2br }, data() { return { user: {}, // ユーザー情報 chat: [], // 取得したメッセージを入れる配列 input: "", // 入力したメッセージ userIds: [], userDatas: [], uid: "", authenticatedUser: "", preview: require("../assets/デフォルト画像.jpg"), }; },

#2つ目

[Vue warn]: Error in render: "TypeError: Cannot read property 'uid' of undefined"

レンダリングのエラー: "TypeError:未定義のプロパティ 'uid'を読み取れません"


1つ目のエラーはuid=""という風に初期化させることで解決しましたが、上記のようなレンダリングエラーが検出されております・・

原因が分からず行き詰まっております。

###試したこと

以上を参考に各テンプレート内でuidを使用している箇所で、v-if="uid"としてデータの取得がされないうちは表示しないようにしましたが、エラーは改善されませんでした。

分かる方いらっしゃいましたらお力添えを頂きたいです。

よろしくお願いいたします。

#chat.vue

<template> <div class="chat"> <div class="chat-header flex"> <h1 class="chat-tll flash neon flex">Chat Room</h1> <slide right disableOutsideClick width="200"> <router-link to="/" class="header-link neon3 flash">HOME</router-link> <router-link to="/about" class="header-link neon3 flash" >ABOUT</router-link > <router-link :to="`/board/${this.uid}`" class="header-link neon3 flash" >POST</router-link > <router-link to="/signup" class="header-link neon3 flash" v-if="!authenticatedUser" >SINGUP</router-link > <router-link to="/signin" class="header-link neon3 flash" v-if="!authenticatedUser" >SINGIN</router-link > <router-link :to="`/mypage/${this.uid}`" class="header-link neon3 flash" >MYPAGE</router-link > </slide> <div id="page-wrap"></div> </div> <!--Firebase から取得したリストを描画--> <transition-group name="chat" tag="div" class="list content"> <!--chatの中の{ key, name, image, message ,userid }をそれぞれ取得--> <section v-for="{ key, name, image, message, userid, time } in chat" :key="key" > <div v-if="userid === user.uid" class="myitem flex"> <!-- 自身 --> <!--「画像」の指定--> <!--「名前」と「メッセージ」の指定--> <div class="mydetail"> <div class="mytime">{{ $dayjs(time).format("HH:mm") }}</div> <div @click.right.prevent="deleteMessage(key)" class="mymessage"> <nl2br tag="div" :text="message" /> </div> </div> <div class="myimage flex"> <img :src="user.photoURL" width="50" height="50" /> <div class="myname flex">{{ user.displayName }}</div> </div> </div> <div v-else class="otheritem flex"> <!-- 自身ではない --> <!--「画像」の指定--> <div class="otherimage flex"> <router-link :to="`/mypage/${returnUserData(userid).uid}`"> <img :src=" returnUserData(userid) ? returnUserData(userid).uploadedImage.fileUrl : preview " width="50" height="50" /> <div class="othername flex"> {{ returnUserData(userid) ? returnUserData(userid).name : "NO NAME" }} </div> </router-link> </div> <!--「名前」と「メッセージ」の指定--> <div class="otherdetail"> <div class="othermessage"> <nl2br tag="div" :text="message" /> </div> <div class="othertime">{{ $dayjs(time).format("HH:mm") }}</div> </div> </div> </section> </transition-group> <!-- 入力フォームの設定 --> <div class="message-inner flex"> <form action @submit.prevent="doSend" class="form flex"> <textarea v-model="input" placeholder="メッセージを入力" :disabled="!user.uid" @keydown.enter.exact.prevent="doSend" ></textarea> <!-- ユーザーでなければ無効化 --> <button type="submit" :disabled="!user.uid" class="send-button"> <img src="../assets/電球.jpg" class="send-img" alt="送信" /> </button> </form> </div> </div> </template>
<script> import firebase from "firebase"; import Nl2br from "vue-nl2br"; import Vue from "vue"; // 改行を <br> タグに変換するモジュール import dayjs from "dayjs"; import { Slide } from "vue-burger-menu"; Vue.component("slide", Slide); dayjs.locale("ja"); Vue.prototype.$dayjs = dayjs; export default { components: { Nl2br }, data() { return { user: {}, // ユーザー情報 chat: [], // 取得したメッセージを入れる配列 input: "", // 入力したメッセージ userIds: [], userDatas: [], uid: "", authenticatedUser: "", preview: require("../assets/デフォルト画像.jpg"), }; }, created() { firebase.auth().onAuthStateChanged((user) => { // ログイン状態ならuserが取得できる this.user = user ? user : {}; //userにはログイン中のユーザー情報(Firebaseのデータ)が保存されている。 const ref_message = firebase.database().ref(this.$route.params.id); if (user) { this.chat = []; //limitToLast(10)で並べ替えられた「ref_message」の最後の10個を取得し、on()で変更があったときのハンドラを登録。 ref_message.limitToLast(10).on("child_added", this.childAdded); } else { //off()は、変更があったときのハンドラを解除 ref_message.limitToLast(10).off("child_added", this.childAdded); } }); }, methods: { // スクロール位置を一番下に移動 scrollBottom() { this.$nextTick(() => { //this.$nextTickは、再描画を待つ。絶対値からbody要素の高さを取得。 window.scrollTo(0, document.body.clientHeight); }); }, childAdded(snap) { const message = JSON.parse(JSON.stringify(snap.val())); if (!this.userIds.includes(String(message.userid))) { this.userIds.push(String(message.userid)); //this.userIds(配列)にuserid含まれていていなければthis.userIds(配列)に追加。 let self = this; firebase .firestore() .collection("users") .doc(message.userid) .get() .then((snapshot) => { self.userDatas.push(snapshot.data()); }); //メッセージを送信したuserid(ログイン中のユーザーid)の情報をuserDatasに保存 } //データベースに新しい要素が追加されると随時呼び出される this.chat.push({ key: snap.key, name: message.name, image: message.image, message: message.message, userid: message.userid, time: message.time, }); this.scrollBottom(); //スクロールの一番下に追加。 }, doSend() { const time = time; if (this.user.uid && this.input.length) { //以下でFirebaseに書き込まれたメッセージを追加 firebase .database() .ref(this.$route.params.id) .push( { message: this.input, name: this.user.displayName, image: this.user.photoURL, userid: this.user.uid, time: firebase.database.ServerValue.TIMESTAMP, }, () => { this.input = ""; //フォームを空にする } ); } }, returnUserData(id) { const userData = this.userDatas.find((user) => user.uid === id); //methodsなので引数に渡した値(id)はtemplate内の引数(userid)を渡していること。 //this.userDatas(配列)に入っている値uesr.uidとidが一致したものを一つuserData(配列)に保存。 return userData; }, deleteMessage(key) { firebase .database() .ref(this.$route.params.id + "/" + key) .remove(); this.$swal({ title: "内容確認", text: "メッセージを削除しますか?", icon: "warning", buttons: true, dangerMode: true, }) .then((willDelete) => { if (willDelete) { this.$swal("メッセージを削除しました", { icon: "success", }); this.$router.go({ path: `/chat/${this.$route.params.id}`, force: true, }); } else { this.$swal("キャンセルしました。"); } }) .catch(() => { this.$swal("メッセージを削除出来ません。", { icon: "error", }); }); }, }, mounted() { //以下、ユーザーが認証済みであれば表示・非表示を設定 firebase.auth().onAuthStateChanged((user) => { const currentUser = firebase.auth().currentUser; this.uid = currentUser.uid; if (user) { this.authenticatedUser = true; } else { this.authenticatedUser = false; } }); }, }; </script>

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

一つずつ消してどこのuidがエラー出ているのか確認していたところ、<router-link>の箇所でして
v-if="returnUserData(userid)"としたら解決いたしました。

<router-link v-if="returnUserData(userid)" :to="`/mypage/${returnUserData(userid).uid}`">

投稿2021/06/14 14:16

TMTN

総合スコア52

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問