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

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

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

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

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

1回答

1014閲覧

【Vue】chartjsをループで複数表示する際に、データを連想配列で紐づけようとしてInvalid prop が発生する

godcat

総合スコア10

Vue.js

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

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2022/06/30 03:36

概要

Vueにおいてchartjsを利用して各ユーザーごとのグラフをループで表示しています。
ユーザーごとのデータを判別するために、連想配列を用いています。

困っている事

グラフは正しく表示されるのですが、コンソールに表示される下記warningが消せません。

[Vue warn]: Invalid prop: type check failed for prop "chartData". Expected Object, got Undefined

想定している流れ

  1. 画面起動時にDBからユーザーのリストを取得する
  2. 各ユーザーの情報をDBから取得する
  3. 取得したユーザーの情報をchartItems[ユーザー名]のオブジェクトに入れる
  4. chartjsでグラフが反映される

試した解決方法

こちらにほぼ回答に近い記事があります。
https://nplll.com/2019/05/vue-chartjs_error/
https://www.ultra-noob.com/blog/2020/50/
しかし解決されませんでした。
chartItems[ユーザー名] = {オブジェクト} という構造の違いが問題でしょうか。。

コード

実際のコードとは異なりますが、簡潔に要所のみを抜き出しています。

js

1<template> 2 <div v-for="User in Users" :key="User.name"> 3 4 <BarChart v-bind:chartData="chartItems[User.name]" :options="Options" :styles="chartSize"/> 5 6 </div> 7</template> 8 9<script> 10 11 data () { 12 return { 13 Users:[] 14 chartItems: { labels:[], datasets: [] }, 15 } 16 }, 17 18 19 created () { 20 this.setChart() 21 }, 22 23 methods:{ 24 setChart(){ 25 this.$axios.$post(/getUsers) 26 .then(res=> { 27 // APIを実行してユーザー情報を取得します。仮に下記のようなデータが取得されると仮定します。 28 this.Users = [{name:"Arisa", id:1111}, {name:"Bob", id:2222}, {name:Charley, id:3333}] 29 }) 30 31 this.Users.foreach(user=>{ 32 var obj = { 33 labels: [1,2,3,4,5], 34 datasets: [{ 35 label: "フォロワー数", 36 data: this.Data[user.name], // 別途APIから取得したData[ユーザー名]の連想配列があります。 37 }] 38 } 39 40 // ここでchartDataにバインドするchartItems[ユーザー名]をセットします。 41 this.$set(this.chartItems, user.name, obj) 42 43 }) 44 } 45 } 46 47</script> 48 49

知りたい事

「レイアウトが作成される段階ではchartItems["Arisa"]やchartItems["Bob"]は存在しないのでwarningが表示されるが、this.$setでchartItems["Arisa"]などが検知されて結果として表示は問題ない」という解釈で相違ないでしょうか。

また、エラーを表示させない方法も知りたいですが、そもそもの画面表示が問題なくできてしまっている以上、このwarningは無視するというのもひとつの解決でしょうか。

素人質問で大変恐縮でございますが、何卒よろしくお願いいたします。

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

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

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

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

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

Matsumon0104

2022/06/30 05:09

コードを簡潔に掲載しているということなので、ケアされているかもしれませんが、 「this.Users」の値は非同期でとられてきていますが、問題ありませんか? 「this.Users.foreach」の時点で「this.Users」は空ではありませんでしょうか。
godcat

2022/06/30 05:22

ご質問頂きありがとうございます。 forEach前にconsole.log(this.Users)で確認すると、中身は記載通りの連想配列がコンソールで確認できます。 ただ、Observerに格納されています。 実はここも少し苦戦した部分で、 ・this.Usersを取得する関数 ・this.Usersを用いてグラフをセットする関数 を並べて実行したところ、仰る通り非同期でthis.Usersが空になってしまっていたので、 現在this.Usersを取得する関数の中で、 this.$axios.post(ユーザー取得API).then(res=> this.Usersに格納してsetChart()を呼び出す) と、axios実行後の処理内部でグラフをセットする関数を呼び出しています。
Matsumon0104

2022/06/30 05:28 編集

レンダーされる瞬間においても、chartItems[User.name]はオブジェクトを返しますでしょうか? エラーメッセージ上では、コンポーネントのpropsとして「Object」で定義されていますが、「Undefined」で受け取っているようです。
godcat

2022/06/30 05:39 編集

申し訳ございません、知識不足で「レンダーされる瞬間」というのをどう確認するかが曖昧なのですが、 mounted()内でchartItemsを出力する事で確認になるでしょうか? mounted()にてconsole.log(chartItems)を実行したところ、 {__ob__: Observer} Arisa: (...) Bob: (...) Charley: (...) datasets: (...) labels: (...) のように表示されました。(...)の中身は全てオブジェクト(labels,datasets)が確認できました。 とはいえ、datasets、labelsが想定と違う場所にいて驚きました。これでは初期値が意味をなしていないですね。
Matsumon0104

2022/06/30 05:43

失礼しました。 「知りたいこと」に書いてありましたね。 今、テストする環境が無いので、下記のようにしたら、warningでますでしょうか? <BarChart v-if="chartItems[User.name]" v-bind:chartData="chartItems[User.name]" :options="Options" :styles="chartSize"/>
godcat

2022/06/30 05:48

warning消えました!! ページ構成時にはまだ存在していないキーについて事前にカラ値を設定するのは無理なのでは、、と思っていたのですが、そもそもの存在判定をしてしまえば済むのですね。なるほど、目から鱗でした。 Matsumon0104様、心より感謝申し上げます。
Matsumon0104

2022/06/30 05:54

上手くいったようでよかったです。 ご質問事項をよく読まなくて、回答を導き出すためにお時間がかかって、申し訳ありませんでした。 自己解決として、回答部に解決方法を記載して質問を閉じていただけますでしょうか。
guest

回答1

0

自己解決

v-ifを追加することで解決できました。

js

1<template> 2 <div v-for="User in Users" :key="User.name"> 3 4 <BarChart v-if="chartItems[User.name]" v-bind:chartData="chartItems[User.name]" :options="Options" :styles="chartSize"/> 5 6 </div> 7</template>

chartItems[User.name]がまだ存在しない時は、後ろのchatDataのbindが関係なくなるので、
結果としてwarningが消えたのだと考えられます。

@Matsumon0104様ご助言のもと解決いたしました。
ありがとうございました!

投稿2022/06/30 06:00

godcat

総合スコア10

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.47%

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

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

質問する

関連した質問