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

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

新規登録して質問してみよう
ただいま回答率
85.35%
JavaScript

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

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

Q&A

解決済

2回答

4764閲覧

プロパティが存在しているのに undefined となってエラーが表示される【React(TS)】

moimoi_sushi

総合スコア26

JavaScript

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

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

0グッド

0クリップ

投稿2020/08/26 12:02

編集2020/08/26 17:00

前提・実現したいこと

オブジェクトの中身を順番に取り出したいのですが存在しているはずの要素が undefined と表示されてしまいます。
エラーとして考える理由がしばらく考えても分からず投稿しました。

発生している問題・エラーメッセージ

エラーメッセージ TypeError: Cannot read property 'Name' of undefined ratioListsLoop src/components/common/parts/card/stuffCard.tsx:126 123 | // console.log(target.name, ratioObj, ratioObj.ratio_lists[i], count); 124 | if(arrRatioList.length < 2){ 125 | console.log(ratioList); > 126 | if(ratioList[i].Name !== targetName) arrRatioList.push(ratioList[i]); | ^ 127 | } 128 | } 129 | console.log(arrRatioList);

property 'Name' は console.logで確認したところ読み込めています。

該当のソースコード

const ratioListsLoop = (ratioList: RatioListType[], targetName: string): RatioListType[] => { let count: number = 3; const arrRatioList = []; for( let i = 0; count > i; i += 1 ){ if(arrRatioList.length < 2){ if(ratioList[i].Name !== targetName) arrRatioList.push(ratioList[i]); } } return arrRatioList; };

関数ratioListsLoopでは、引数:ratioListのキーNameとtargetNameの中身が同じ場合は空の配列であるarrRatioListへ何もpushせずにfor文を回すようにしています。

音のオブジェクトの中身

配列の中に食品成分がobjectで入っています。ratioListの中身は下記の通りです。

ratioList

1[ 2 { 3 "Name": "Molybdenum", 4 "nameJP": "モリブデン", 5 "Ratio": 70.8 6 }, 7 { 8 "Name": "Biotin", 9 "nameJP": "ビオチン", 10 "Ratio": 19.56 11 }... 12]

試したこと

関数ratioListsLoopの結果を受け取る場所を変える程度はしましたがわからず。データを同時に処理しているのでそれが関係しているのかなと思ったり、でもどうすれば良いのかもわかりませんでした。

追記:エラー直前のbreakpointを貼りました

イメージ説明

↑恥ずかしながらコードがごちゃごちゃしていてすみません。エラー直前のbrekapoint時の中身の方を示す目的で貼りました。
ratioListの要素2(セレン)で引っ掛かります。

{Name: "Selenium", nameJP: "セレン", Ratio: 1.2}

ちなみにこの箇所以外でも引っかかるためこのratioListだけの問題ではないようです。

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

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

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

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

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

guest

回答2

0

ベストアンサー

TypeError

TypeScriptからJavaScriptにコンパイルしたとして、

JavaScript

1"use strict"; 2const ratioListsLoop = (ratioList, targetName) => { 3 let count = 3; 4 const arrRatioList = []; 5 for (let i = 0; count > i; i += 1) { 6 if (arrRatioList.length < 2) { 7 if (ratioList[i].Name !== targetName) 8 arrRatioList.push(ratioList[i]); 9 } 10 } 11 return arrRatioList; 12};

最も気になるのは、ratioList.length < 2 である場合にTypeErrorになる事です。

JavaScript

1ratioListsLoop([], 'foo'); // TypeError: Cannot read property 'Name' of undefined 2ratioListsLoop([1], 'bar'); // TypeError: Cannot read property 'Name' of undefined

デバッグ手段

  • TypeError直前にbreakpointを設置する
  • TypeError直前で console.log(JSON.stringify(arrRatioList))

切り分け

切り分けポイント

  1. TypeErrorが発生する最小限のコードは「****」である
  2. 「プロパティが存在しない」or「プロパティに undefined 値が代入されている」
  3. プロパティは「直属のプロパティである」or「prototype-chain 上のプロパティである」
  4. プロパティは「静的プロパティである」or「getterプロパティである」「new Proxyのtrapプロパティである」

(Q1) エラーコードの特定
下記コードで「TypeError: Cannot read property 'Name' of undefined」が発生しますか
(※エラーメッセージが異なれば、当該エラーメッセージを添えてください)

JavaScript

1ratioList[i].Name; // TypeError: Cannot read property 'Name' of undefined

(Q2) プロパティ状態の特定
下記コードの出力結果を教えてください

JavaScript

1console.log(i, i in ratioList, Object.prototype.hasOwnProperty.call(ratioList, i), ratioList[i]); 2console.log(Object.getOwnPropertyDescriptor(ratioList, i));

Re: moimoi_sushi さん

投稿2020/08/26 12:45

編集2020/08/26 22:10
think49

総合スコア18189

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

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

moimoi_sushi

2020/08/26 13:11 編集

console.log(JSON.stringify(arrRatioList))でエラー直前に返ってきたarrRatio配列は[{"Name":"VitaminK","nameJP":"ビタミンK","Ratio":0.08}]になりました。 この次の要素は {Name: "RetinolActiveEquivalent", nameJP: "ビタミンA", Ratio: 0.493} となっていて、これがNameとして呼び出されるはずが 'undefined' となってしまっています。 Name: "RetinolActiveEquivalent"と、一応はstring型として入っています(いるはず)。
moimoi_sushi

2020/08/26 13:08

>最も気になるのは、ratioList.length < 2 である場合にTypeErrorになる事です。 そうですね。ここが怪しいとは思うものの手がかりがわからず。書き方を変えてみます。 補足として、ratioList.length < 2の意図はratioList要素のトップ2つを取得したいためのコードです。 ratioListはループで回す前にsortしていてratio率の高い順に並べております。 トップ2つの要素(ただしtargetNameと重なった場合は無視)を取得して描写するのを目的として(ratioList.length < 2)を挟んでいます。
think49

2020/08/26 13:19

「デバッグ手段」の結果はどうなっていますか
moimoi_sushi

2020/08/26 17:01 編集

遅くなりすみません。追記で質問の一番下の方に貼りました!
think49

2020/08/26 21:47

> 追記:エラー直前のbreakpointを貼りました 「当該break直後にTypeErrorが発生した」という前提で正しいでしょうか。
think49

2020/08/26 21:49

先の前提が正しいと仮定して、TypeErrorが発生するのは if(ratioList[i].Name !== targetName) arrRatioList.push(ratioList[i]); となり、 ratioList[i].Name; // TypeError: Cannot read property 'Name' of undefined となり、 i = 1 console.log(ratioList[i] === undefined); // true となり、 console.log(i in ratioList); // true or false の結果で ①プロパティ「1」が存在しない ②プロパティ「1」に undefined が代入されている のどちらのケースか特定できるはずです。 その観点で切り分けを行ってください。 --- まとめて切り分けすると、下記になると思います。 console.log(i, i in ratioList, Object.prototype.hasOwnProperty.call(ratioList, i), ratioList[i]); ratioList[i].Name; // TypeError: Cannot read property 'Name' of undefined 上記2行の結果を教えてください。
moimoi_sushi

2020/08/30 13:24

結果としてエラー解消できました。私情もあったのですが返事遅くなりすみません汗 エラーをchromeデベロッパーツールのconsole画面から遡ってみたところ、ratioListの中身が2つしか入っていないところでエラーが生じていました(正常なエラーだった)。 一番末尾のエラーメッセージしかみておらず、そこは質問の通りプロパティが存在しているはずなのにundefinedとなっていました。 そこで通常通りのエラーに対処するため要素が2つ以下の場合の条件分岐を挟み、するとまた別のエラー(ratioListを含むオブジェクト)が undefined と表示されてまた対処...という形でひとまず動かすところまでできました キリの良いところで返事しようと思い遅れました
think49

2020/08/30 13:39

> エラーをchromeデベロッパーツールのconsole画面から遡ってみたところ、ratioListの中身が2つしか入っていないところでエラーが生じていました(正常なエラーだった)。 プロパティが2つ存在しているのなら、TypeErrorになりえません。 再発防止の為、原因を特定しておく事をお勧めします。 > 一番末尾のエラーメッセージしかみておらず、そこは質問の通りプロパティが存在しているはずなのにundefinedとなっていました。 「プロパティが存在しているはずなのにundefined」はそれが静的プロパティであるなら、原理的に考えられません。 new Proxyやgetterで動的にプロパティを生成しているなら、参照方法によって結果が変わる事はありえるので、「2つあると確認したコード」と「TypeErrorが発生するコード」で結果が変わる事はありえますが、そういうことなのでしょうか。 こちらも原因を特定しておいたほうが良いでしょう。 --- そもそもですが、要素数が固定値ではないにも関わらず、index0,1を決め打ちで判定する関数 ratioListsLoop の実装に問題がある気がしないでもありません。 全体の設計を見ていないので、正確なことはいえませんが…。
moimoi_sushi

2020/08/31 07:15 編集

アドバイス助かります。 >プロパティが2つ存在しているのなら、TypeErrorになりえません ratioList[i].Name === targetName の場合はそのプロパティを push せずにスルーしています。 したがってプロパティが2つ以下でかつ ratioList[i].Name === targetName が成立すると Type Error が生じます。 >「プロパティが存在しているはずなのにundefined」はそれが静的プロパティであるなら、原理的に考えられません。 おっしゃる通りだと思います。ググっても分からず質問したのもこことのところで引っかかったため。 プロパティは静的であるため(既存データを参照)、引っ張ってくる経緯でプロパティデータに不具合が生じた〜ということはなさそうです。 >要素数が固定値ではないにも関わらず、index0,1を決め打ちで このコードの背景を2つ説明すると、 1. ファイル単位で実現したかったことは上位2つの栄養素の比率(ratio)を取得してそれをView側でタグとして表示したい。というものがありました。 上位2つの栄養素を取得するために index0,1 で決め打ちして上位2つを取得していました。(流石に2つ取得できなかった場合の条件式は回答をいただきコードを修正した後に埋め込みました) もっと良い書き方があればそちらにリファクタしたいと思っています。 2. ratioListのプロパティは本来は1つのデータにつき 63件 ありました。しかし引っ張ってきた静的データは加工したもので、加工する際にratioがおよそ 0 のものは切り捨てました。データの量を減らして読み込みを速くしたいためそのようにしました。その結果、ratioListの要素数が不定となりました。
guest

0

月並ですが、ループを回している時点でratioListは3件以上データが入っていますか?(console.log(ratioList)とかで確認されてますか?)
count=3なのでratioListが3件未満だとundefiendになると思いますが・・・

投稿2020/08/26 12:21

nekoniki

総合スコア2411

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

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

moimoi_sushi

2020/08/26 12:46

エラーに該当したratioListは20件入っている感じです
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問