実現したいこと
現在発生しているエラー
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')
1) エラーが発生しているのに、それより後のコードが実行されているのが不思議ですがエラーの発生箇所は、ここに書いていない部分ということはないですか。
2) mapのところで(と)とが対応していません(findのところのようになるはず)が実際のコードと違う部分がありませんか。
1)エラーの箇所についてですが、当該部分の
var Data3 = Data3Obj.map((obj)=>obj.name);
と
console.log(Data3)
をコメントアウトするとエラーなく実行できるため、発生箇所はここで間違いないんではないかと思います。
>エラーが発生しているのに、それより後のコードが実行されているのが不思議ですが
そうなんですよね、、、、
2)ご指摘ありがとうございます。修正しました。
エラーに発生したコードの行番号が表示されていないのですか?
info の値を変えて、該当のソースコードが複数回実行されてるってことでは?
皆さんご意見ありがとうございます。
>YellowGreenさん
はい。エラーが出ている行数は表示されていてvar Data3 = Data3Obj.map((obj)=>obj.name);の行数が表示されています。
>hoshi-takanoriさん
だとすると、infoを参照している他の箇所でもエラーが出ないのはどうしてなんでしょう。。。
次のスクリプトを実行してもエラーは発生しません。
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)
}
>YellowGreenさん
検証までしていただいてありがとうございます。
初めからそうしろという話なのですが、質問を編集して現在作成中のコードの全体像を載せました。
先ほど言った通りvar Data3 = Data3Obj.map((obj) => obj.name);をコメントアウトすればエラーなく実行できること、他のDataを配列化しようとしている部分にエラーが発生していないことから、当初推せていた部分のコードのみで問題ないかと考えておりました。
APIで取得したデータ中の配列内オブジェクトから特定keyの値を抜き出して配列化する、ということをやろうとしています。APIで取得したデータの全体像も載せました。
何かお分かりになることがあれば教えていただけると幸いです。
エラーになっている部分はforで繰り返し実行されるため、もしエラーが発生しなければ、スプレッドシートにあるデータの数だけ8行目のApiUrlが生成されて
[ '北海道', '青森', '岩手', '秋田', '福島', '山形', '新潟' ]
[ '北' ]
[ '北海道', '青森', '岩手', '秋田' ]
[ '東北' ]
と同じようなログが出力され続けるはずですが、このエラーが発生しているためスプレッドシート上のデータを1行処理しただけで止まってしまう状態です。
var Data3 = Data3Obj.map((obj) => obj.name);
これがなければ行数分だけ処理が行われます。
改めて編集後の質問でお示しいただいたデータをそのまま使い、
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)
}
}
>YellowGreenさん
検証ありがとうございます。
>取得しているデータに構造が違うものがあるということではないでしょうか。
データの形式は質問の記載のものと同じ形になるはずなのですが、もう少し調べてみます。ありがとうございます。
もし他に当該エラーが発生する原因で考えられるものがあれば教えていただけると幸いです。
エラーについて調べても、発生するシチュエーションに心当たりがないもので。。。
> 同じ形になるはず
「はず」は当てになりませんので、確認すべきです。
2度目にエラーが発生しているのであれば、繰り返し処理の中の
// var Data3Obj = info.data3;
// var Data3 = Data3Obj.map((obj) => obj.name);
if (i == 2) {
console.log(info.data3);
}
として中身を確認してみてはいかがでしょうか?
>YellowGreenさん
大変失礼しました。データ内を確認したところ、スプレッドシート2行目のデータを参照したinfo.data3の値がundefinedになっていたというとても単純なことが理由でした。
対象の部分のコードを
var Data3Obj = info.data3;
if(Data3Obj === undefined){
var Data3 = '-';
}else{
var Data3 = Data3Obj.map((obj)=>obj.name);
}
としたところ、エラーが解消され実行できるようになりました。
お騒がせして大変申し訳ございません。
回答1件
あなたの回答
tips
プレビュー