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

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

新規登録して質問してみよう
ただいま回答率
85.37%
Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

オブジェクト

オブジェクト指向において、データとメソッドの集合をオブジェクト(Object)と呼びます。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

解決済

1回答

7324閲覧

エラー:Cannot read properties of undefinedの発生理由がわからない(GAS)

nari3

総合スコア2

Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

オブジェクト

オブジェクト指向において、データとメソッドの集合をオブジェクト(Object)と呼びます。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

0グッド

0クリップ

投稿2023/04/21 15:25

編集2023/04/22 01:36

実現したいこと

現在発生しているエラー
TypeError: Cannot read properties of undefined (reading 'map')
を解消したいです。

前提

APIで取得したデータを使い、配列内のオブジェクトから特定のkeyの値のみの配列を作る、ということをしていました。

GAS

1function myFunction() { 2 var spreadsheet = SpreadsheetApp.getActiveSpreadsheet(); 3 var sheet = spreadsheet.getSheetByName('テスト'); 4 var values = sheet.getDataRange().getValues(); 5 var LastRow = sheet.getLastRow(); 6 7 for(let i =1; i<LastRow; i++){ 8 var ApiUrl = 'https://apiurl' + values[i][0] 9 var ApiCell = sheet.getRange(i+1,2); 10 var res = UrlFetchApp.fetch(ApiUrl).getContentText(); 11 var res_json = JSON.parse(res); 12 var res_json_result1 = res_json.result; 13 var res_json_result2 = res_json_result1.items; 14 var res_json_result3 = res_json_result2[0]; 15 var p_code = res_json_result3.p_code; 16 var user = res_json_result3.username; 17 var date = res_json_result3.date; 18 var StartDate = date.start; 19 var info = res_json_result3.iteminfo; 20 var Data1Obj = info.data1; 21 var Data1 = Data1Obj.map((obj)=>obj.name); 22 var Data2Obj = info.data2; 23 var Data2 = Data2Obj.map((obj)=>obj.name); 24 var Data3Obj = info.data3; 25 var Data3 = Data3Obj.map((obj)=>obj.name); 26 var Data4Obj = info.data4; 27 var Data4 = Data4Obj.map((obj)=>obj.name); 28 29 console.log(Data1) 30 console.log(Data2) 31 console.log(Data3) 32 console.log(Data4) 33 } 34} 35

取得したデータの全体像console.jog(res_json)が以下です。

{ request: { parameters: { api_id: 'apiid', username: 'USERNAME', email: 'xyz@example.jp', output: 'json' } }, result: { status: 200, result_count: 1, items: [ { p_code: 'xxx', p_name: '', username: 'USERNAME', email: 'xyz@example.jp', date: { start: '2022-11-5', finish: '2022-11-11' }, iteminfo: { data1: [ { id: 1111, name: '北海道' }, { id: 1112, name: '青森' }, { id: 1113, name: '岩手' }, { id: 1114, name: '秋田' }, { id: 1115, name: '福島' }, { id: 1116, name: '山形' }, { id: 1117, name: '新潟' } ], data2: [ { id: 4600, name: '北' } ], data3: [ { id: 1111018, name: '北海道', ruby: 'ほっかいどう' }, { id: 1112018, name: '青森', ruby: 'あおもり' }, { id: 1113018, name: '岩手', ruby: 'いわて' }, { id: 1114018, name: '秋田', ruby: 'あきた' } ], data4: [ { id: 7020, name: '東北' } ] }

上記のようにしたところ、ログがそれぞれ
[ '北海道', '青森', '岩手', '秋田', '福島', '山形', '新潟' ]
[ '北' ]
[ '北海道', '青森', '岩手', '秋田' ]
[ '東北' ]
と出力されたのですが、質問タイトルにも書いたエラーが発生してしまいます。

var Data3 = Data3Obj.map((obj))=>obj.name);

エラーとなっているのは、この部分のようです。
mapは、keyが3つ以上あるオブジェクトには機能しないなんてことありますでしょうか、、

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

TypeError: Cannot read properties of undefined (reading 'map')

該当のソースコード

GAS

1function myFunction() { 2 var spreadsheet = SpreadsheetApp.getActiveSpreadsheet(); 3 var sheet = spreadsheet.getSheetByName('テスト'); 4 var values = sheet.getDataRange().getValues(); 5 var LastRow = sheet.getLastRow(); 6 7 for(let i =1; i<LastRow; i++){ 8 var ApiUrl = 'https://apiurl' + values[i][0] 9 var ApiCell = sheet.getRange(i+1,2); 10 var res = UrlFetchApp.fetch(ApiUrl).getContentText(); 11 var res_json = JSON.parse(res); 12 var res_json_result1 = res_json.result; 13 var res_json_result2 = res_json_result1.items; 14 var res_json_result3 = res_json_result2[0]; 15 var p_code = res_json_result3.p_code; 16 var user = res_json_result3.username; 17 var date = res_json_result3.date; 18 var StartDate = date.start; 19 var info = res_json_result3.iteminfo; 20 var Data1Obj = info.data1; 21 var Data1 = Data1Obj.map((obj)=>obj.name); 22 var Data2Obj = info.data2; 23 var Data2 = Data2Obj.map((obj)=>obj.name); 24 var Data3Obj = info.data3; 25 var Data3 = Data3Obj.map((obj)=>obj.name); 26 var Data4Obj = info.data4; 27 var Data4 = Data4Obj.map((obj)=>obj.name); 28 29 console.log(Data1) 30 console.log(Data2) 31 console.log(Data3) 32 console.log(Data4) 33 } 34} 35

試したこと

合っているかわからないのですが、エラーになっている部分を

GAS

1var Data3 = Data3Obj.find((item) => item.name);

に変えてみたところ、エラーが以下になっただけでした。

TypeError: Cannot read properties of undefined (reading 'find')

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

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

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

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

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

YellowGreen

2023/04/21 17:21

1) エラーが発生しているのに、それより後のコードが実行されているのが不思議ですがエラーの発生箇所は、ここに書いていない部分ということはないですか。 2) mapのところで(と)とが対応していません(findのところのようになるはず)が実際のコードと違う部分がありませんか。
nari3

2023/04/21 17:52

1)エラーの箇所についてですが、当該部分の var Data3 = Data3Obj.map((obj)=>obj.name); と console.log(Data3) をコメントアウトするとエラーなく実行できるため、発生箇所はここで間違いないんではないかと思います。 >エラーが発生しているのに、それより後のコードが実行されているのが不思議ですが そうなんですよね、、、、 2)ご指摘ありがとうございます。修正しました。
YellowGreen

2023/04/21 18:49

エラーに発生したコードの行番号が表示されていないのですか?
hoshi-takanori

2023/04/21 20:36

info の値を変えて、該当のソースコードが複数回実行されてるってことでは?
nari3

2023/04/22 00:43

皆さんご意見ありがとうございます。 >YellowGreenさん はい。エラーが出ている行数は表示されていてvar Data3 = Data3Obj.map((obj)=>obj.name);の行数が表示されています。 >hoshi-takanoriさん だとすると、infoを参照している他の箇所でもエラーが出ないのはどうしてなんでしょう。。。
YellowGreen

2023/04/22 00:53

次のスクリプトを実行してもエラーは発生しません。 function myFunction() { var info = { data1: [{ id: 1111, name: '北海道' }, { id: 1112, name: '青森' }, { id: 1113, name: '岩手' }, { id: 1114, name: '秋田' }, { id: 1115, name: '福島' }, { id: 1116, name: '山形' }, { id: 1117, name: '新潟' }], data2: [{ id: 4600, name: '北' }], data3: [{ id: 1111018, name: '北海道', ruby: 'ほっかいどう' }, { id: 1112018, name: '青森', ruby: 'あおもり' }, { id: 1113018, name: '岩手', ruby: 'いわて' }, { id: 1114018, name: '秋田', ruby: 'あきた' }], data4: [{ id: 7020, name: '東北' }] } var Data1Obj = info.data1; var Data1 = Data1Obj.map((obj) => obj.name); var Data2Obj = info.data2; var Data2 = Data2Obj.map((obj) => obj.name); var Data3Obj = info.data3; var Data3 = Data3Obj.map((obj) => obj.name); var Data4Obj = info.data4; var Data4 = Data4Obj.map((obj) => obj.name); console.log(Data1) console.log(Data2) console.log(Data3) console.log(Data4) }
nari3

2023/04/22 01:42

>YellowGreenさん 検証までしていただいてありがとうございます。 初めからそうしろという話なのですが、質問を編集して現在作成中のコードの全体像を載せました。 先ほど言った通りvar Data3 = Data3Obj.map((obj) => obj.name);をコメントアウトすればエラーなく実行できること、他のDataを配列化しようとしている部分にエラーが発生していないことから、当初推せていた部分のコードのみで問題ないかと考えておりました。 APIで取得したデータ中の配列内オブジェクトから特定keyの値を抜き出して配列化する、ということをやろうとしています。APIで取得したデータの全体像も載せました。 何かお分かりになることがあれば教えていただけると幸いです。
nari3

2023/04/22 01:50 編集

エラーになっている部分はforで繰り返し実行されるため、もしエラーが発生しなければ、スプレッドシートにあるデータの数だけ8行目のApiUrlが生成されて [ '北海道', '青森', '岩手', '秋田', '福島', '山形', '新潟' ] [ '北' ] [ '北海道', '青森', '岩手', '秋田' ] [ '東北' ] と同じようなログが出力され続けるはずですが、このエラーが発生しているためスプレッドシート上のデータを1行処理しただけで止まってしまう状態です。 var Data3 = Data3Obj.map((obj) => obj.name); これがなければ行数分だけ処理が行われます。
YellowGreen

2023/04/22 02:06

改めて編集後の質問でお示しいただいたデータをそのまま使い、 APIから値を取得しないで変数に直接代入するように 一部のコードをコメントに変えるなどしてから、 A列の2行目以降に適当な値を入れておいて実行しても エラーにならず、A列の値の数だけ繰り返しログが出力されたので、 取得しているデータに構造が違うものがあるということではないでしょうか。 function myFunction() { var res_json = {//★繰り返し処理の中では毎回これを取得する。 request: { parameters: { api_id: 'apiid', username: 'USERNAME', email: 'xyz@example.jp', output: 'json' } }, result: { status: 200, result_count: 1, items: [{ p_code: 'xxx', p_name: '', username: 'USERNAME', email: 'xyz@example.jp', date: { start: '2022-11-5', finish: '2022-11-11' }, iteminfo: { data1: [{ id: 1111, name: '北海道' }, { id: 1112, name: '青森' }, { id: 1113, name: '岩手' }, { id: 1114, name: '秋田' }, { id: 1115, name: '福島' }, { id: 1116, name: '山形' }, { id: 1117, name: '新潟' }], data2: [{ id: 4600, name: '北' }], data3: [{ id: 1111018, name: '北海道', ruby: 'ほっかいどう' }, { id: 1112018, name: '青森', ruby: 'あおもり' }, { id: 1113018, name: '岩手', ruby: 'いわて' }, { id: 1114018, name: '秋田', ruby: 'あきた' }], data4: [{ id: 7020, name: '東北' }] } }] } } var spreadsheet = SpreadsheetApp.getActiveSpreadsheet(); var sheet = spreadsheet.getSheetByName('シート1'); var values = sheet.getDataRange().getValues(); var LastRow = sheet.getLastRow(); for (let i = 1; i < LastRow; i++) { // var ApiUrl = 'https://apiurl' + values[i][0] // var ApiCell = sheet.getRange(i + 1, 2); // var res = UrlFetchApp.fetch(ApiUrl).getContentText(); // var res_json = JSON.parse(res);//★ここが上の変数に置き換わる。 var res_json_result1 = res_json.result; var res_json_result2 = res_json_result1.items; var res_json_result3 = res_json_result2[0]; var p_code = res_json_result3.p_code; var user = res_json_result3.username; var date = res_json_result3.date; var StartDate = date.start; var info = res_json_result3.iteminfo; var Data1Obj = info.data1; var Data1 = Data1Obj.map((obj) => obj.name); var Data2Obj = info.data2; var Data2 = Data2Obj.map((obj) => obj.name); var Data3Obj = info.data3; var Data3 = Data3Obj.map((obj) => obj.name); var Data4Obj = info.data4; var Data4 = Data4Obj.map((obj) => obj.name); console.log(Data1) console.log(Data2) console.log(Data3) console.log(Data4) } }
nari3

2023/04/22 02:44

>YellowGreenさん 検証ありがとうございます。 >取得しているデータに構造が違うものがあるということではないでしょうか。 データの形式は質問の記載のものと同じ形になるはずなのですが、もう少し調べてみます。ありがとうございます。 もし他に当該エラーが発生する原因で考えられるものがあれば教えていただけると幸いです。 エラーについて調べても、発生するシチュエーションに心当たりがないもので。。。
YellowGreen

2023/04/22 03:21 編集

> 同じ形になるはず 「はず」は当てになりませんので、確認すべきです。 2度目にエラーが発生しているのであれば、繰り返し処理の中の // var Data3Obj = info.data3; // var Data3 = Data3Obj.map((obj) => obj.name); if (i == 2) { console.log(info.data3); } として中身を確認してみてはいかがでしょうか?
nari3

2023/04/22 05:05

>YellowGreenさん 大変失礼しました。データ内を確認したところ、スプレッドシート2行目のデータを参照したinfo.data3の値がundefinedになっていたというとても単純なことが理由でした。 対象の部分のコードを var Data3Obj = info.data3; if(Data3Obj === undefined){ var Data3 = '-'; }else{ var Data3 = Data3Obj.map((obj)=>obj.name); } としたところ、エラーが解消され実行できるようになりました。 お騒がせして大変申し訳ございません。
guest

回答1

0

自己解決

info.data3の値がundefinedになっていたというとても単純なことが理由でした。
対象の部分のコードを
var Data3Obj = info.data3;
if(Data3Obj === undefined){
var Data3 = '-';
}else{
var Data3 = Data3Obj.map((obj)=>obj.name);
}
としたところ、エラーが解消され実行できるようになりました。

投稿2023/04/22 05:06

nari3

総合スコア2

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.37%

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

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

質問する

関連した質問