【Vue.js】配列、オブジェクトを参照した際のエラーと対策

Vue.js

みなさんこんにちは、現役エンジニアのサメハックです

アパレル企業でトップ販売員を経て
未経験からWebエンジニアに転職し、
現在正社員として5年働いています!

Vue.jsの解説シリーズです。

今回は配列やオブジェクトを扱う際に発生するエラーの対策方法について学んでいきましょう!

駆け出しエンジニアや未経験の方、
また新入社員を指導する先輩社員にとっても
わかりやすいように解説していきます!

この記事を読むと・・・
  • 配列やオブジェクトのプロパティを表示した際に何故かエラーが発生するのを防げる
今回は配列に焦点を当てているけど、オブジェクトも同じだよ!

Vue.jsで配列を扱ったときによく発生するエラーとは

このようにVue.jsで配列を扱った際に、画面上では正しく表示されているのに
何故かコンソールにエラーが発生していることがあります。

See the Pen Vue.js配列エラー by samehack (@samehack) on CodePen.

該当のコードはこのようになっております。

今回はこのエラーの回避策と原因について解説していきます。

配列とオブジェクトについて復習したい方はこちら!

【JavaScript】配列の作り方【array】
この記事を読むと・・・ 配列の作り方がわかる 配列のデータの取得ができる 配列とオブジェクトの違いがわかる
【JavaScript】オブジェクトを世界一わかりやすく解説!!自信あり【key, value】
JavaScriptのオブジェクトをこれ以上無いくらい分かりやすく解説しました この記事を読むと・・・ オブジェクトの概念が理解できる オブジェクトから期待の値を取得できる

今回発生したエラーとは

今回発生したエラーは以下です。
Cannot read properties of undefined (reading ‘name’)
未定義のプロパティを読み取ることができません

つまり、{{userList[1].name}}の部分に対して
userList[1]がundefinedなので、nameプロパティは参照できないよ!という意味です。

そうです、よく見るあれです。

あれ?エラーなのになんでブラウザ上には名前が表示されているの???

と思った方も多いと思います。

では、実験としてnameプロパティを指定せず、
userList[1]を参照してみましょう。

{{userList[1].name}}       →      {{userList[1]}}

userListの1番目の情報がすべて表示され、エラーはなくなりました。
なぜエラーが消えたのか、引き続き解説していきます。

エラーが発生する条件とは

このようなエラーは2つの条件を満たした際に発生します。

  • 配列の要素のプロパティを指定している
  • 非同期処理で配列データを取得している

なぜプロパティを指定したときにのみエラーが発生するのか

結論から言うと、画面の初期表示時点ではデータ取得が完了していないからです。

ここではfetch関数を使ってデータを取得していますが、
fetch関数は非同期処理なので、画面初期表示の段階ではデータは取得できていません。

つまり、userListの値は初期値である[]のままです。

非同期処理について復習したい方はこちら!

【JavaScript】同期処理と非同期処理【わかりやすく図解!】

前述したように、プロパティを指定するとエラーの発生状況が変わりました。
{{userList[1]}} → エラー発生せず
{{userList[1].name}} → エラー発生

ご存知のように、Vue.jsではマスタッシュ構文内{{}}はJavaScriptの世界です。
今回発生したエラーは単純にJavaScriptのエラーです。

// 空の配列を作成
const userList=[]

// 配列の1番目の要素を取り出す
console.log(userList[1])
// → undefined


// 配列の1番目の要素のnameプロパティを取り出す
console.log(userList[1].name)
// → エラー

つまり、以下のいずれの記述も初期表示段階ではデータ自体が取得出来ていないものの
たまたまエラーが発生するかしないかの違いがあっただけです。


{{userList[1]}} → undefined※JavaScriptではエラーではない
{{userList[1].name}} → undefinedのプロパティは参照出来ないのでエラー

なぜ画面は正しく描画されるのか

{{userList[1].name}}とした場合に、エラーが発生しているにも関わらず
なぜ画面が正しく描画されたのか?と疑問を感じると思いますが
初期表示ではエラーが発生したがデータ取得後に値が更新されただけです。

Vue.jsは双方向データバインディングなので、
JavaScriptの値が更新されると、ブラウザの値も更新されるよ!

エラーの発生を防ごう

今回のようなエラーを防ぐには、画面に渡す初期値に注目する必要があります。

data() {
  return { 
    userList: [] 
  };
},

現在は空のブラケット[]を初期値として設定していますが、
1番目までの子要素に空のオブジェクトを設定することで
エラーを回避することができます。

data() {
  return { 
       userList: [{}, {}]
  };
},

このように書き換えることで、
userList[1].name の値がundefinedとなり、
意図しないエラーの発生を防ぐことが出来ます。

なぜエラーではなくundefinedになったのかは
以下のコードを見てみるとわかります。

// 空のオブジェクト{}を2つ持つ配列を作成
const userList=[{},{}]

// 配列の1番目の要素を取り出す
console.log(userList[1])
// → {}


// 配列の1番目の要素のnameプロパティを取り出す
console.log(userList[1].name)
// → undefined

ポイントはuserList[1]の値が{}となった点です。

See the Pen Vue.js配列エラー対策 by samehack (@samehack) on CodePen.

{}の中のnameプロパティを参照すると、
undefinedつまり未定義という値が取得されるのでエラーは消えたよ!

まとめ

  • Vue.jsでは非同期処理のデータ取得より先に画面描画が行われる
  • 配列の子要素のプロパティを参照する際は、初期値に空の値をいれておく
  • オブジェクトの下層プロパティを参照する際も同じ

満足いただけたら、1クリックなのでSNSフォローしてもらえると嬉しいです🦈

タイトルとURLをコピーしました