Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

JSONのオブジェクトの値が無い時 無視して先に進めたい

解決したいこと

AmazonのAPIを叩いて結果を返すLINE BotをJavaScriptで作成しています。
検索ワードによってはJSONのオブジェクト値が無い時があり、そ都度エラーで止まります。
その部分を無視して先に進める方法を教えて頂きたいです。

コード全文と動いている様子

 

全体コードはこちら(クリックで表示)


// ########################################
//               初期設定など
// ########################################

// パッケージを使用します
const express = require('express');
const line = require('@line/bot-sdk');
const axios = require('axios');

// ローカル(自分のPC)でサーバーを公開するときのポート番号です
const PORT = process.env.PORT || 3000;

// Messaging APIで利用するクレデンシャル(秘匿情報)です。
const config = {
    channelSecret: '****',
    channelAccessToken: '****'
};





const sampleFunction = async (event) => {

const tag2 = event.message.text
            const res = await axios.get('https://ja.wikipedia.org/api/rest_v1/page/summary/' + encodeURIComponent(tag2));
            const item = res.data;

            console.log(item.thumbnail?.source);
            if (item.thumbnail?.source === undefined) {
              return Promise.resolve(null);
          }
            
            result1 = item.extract;
            result2 = item.thumbnail?.source;
            result3 = item.content_urls.mobile.page;
            // ターミナルにも検索結果を出しておきます
            console.log(`「${tag2}」の検索結果:${item.content_urls.mobile.page}`);

            return client.replyMessage(event.replyToken,[ {
                type: 'text',
                text: result1
            },
            {
                type: 'image',
                originalContentUrl: result2,
                previewImageUrl: result2
              },
            {
                type: 'text',
                text: result3
            }

        ])         

};



// ########################################
//  LINEサーバーからのWebhookデータを処理する部分
// ########################################

// LINE SDKを初期化します
const client = new line.Client(config);

// LINEサーバーからWebhookがあると「サーバー部分」から以下の "handleEvent" という関数が呼び出されます
async function handleEvent(event) {
    // 受信したWebhookが「テキストメッセージ以外」であればnullを返すことで無視します
    if (event.type !== 'message' || event.message.type !== 'text') {
        return Promise.resolve(null);
    }
    // サンプル関数を実行します
    return sampleFunction(event);
}



// ########################################
//          Expressによるサーバー部分
// ########################################

// expressを初期化します
const app = express();

// HTTP POSTによって '/webhook' のパスにアクセスがあったら、POSTされた内容に応じて様々な処理をします
app.post('/webhook', line.middleware(config), (req, res) => {
  
  // 検証ボタンをクリックしたときに飛んできたWebhookを受信したときのみ以下のif文内を実行
  if (req.body.events.length === 0) {
    res.send('Hello LINE BOT! (HTTP POST)'); // LINEサーバーに返答します(なくてもよい)
    console.log('検証イベントを受信しました!'); // ターミナルに表示します
    return; // これより下は実行されません
  } else {
    // 通常のメッセージなど … Webhookの中身を確認用にターミナルに表示します
    console.log('受信しました:', req.body.events);
  }

  // あらかじめ宣言しておいた "handleEvent" 関数にWebhookの中身を渡して処理してもらい、
  // 関数から戻ってきたデータをそのままLINEサーバーに「レスポンス」として返します
  Promise.all(req.body.events.map(handleEvent)).then((result) => res.json(result));
});

// 最初に決めたポート番号でサーバーをPC内だけに公開します
// (環境によってはローカルネットワーク内にも公開されます)
app.listen(PORT);
console.log(`ポート${PORT}番でExpressサーバーを実行中です…`);

動いている様子

使用しているAPI

https://ja.wikipedia.org/api/rest_v1/page/summary/"検索したいワード"

例)

https://ja.wikipedia.org/api/rest_v1/page/summary/宇多田ヒカル

取得したい3つの値

const item = res.data;
result1 = item.extract;
result2 = item.thumbnail.source;
result3 = item.content_urls.mobile.page;

取得後 LINEBotで返却したい項目

return client.replyMessage(event.replyToken,[ {
    type: 'text',
    text: result1
    },
    {
    type: 'image',
    originalContentUrl: result2,
    previewImageUrl: result2
    },
    {
    type: 'text',
    text: result3
    }

検索ワードによってはresult2のオブジェクトが存在しない

例)

https://ja.wikipedia.org/api/rest_v1/page/summary/Mr.Children

表示されるエラー

            result2 = item.thumbnail.source;
                                     ^

TypeError: Cannot read properties of undefined (reading 'source')
    at sampleFunction (C:\Users\************)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at async Promise.all (index 0)

ここで毎回止まってしまいます

成し遂げたいこと

「result2」の値が無い場合は、result1とresult3の値のみLINE Botで返したい

const item = res.data;
result1 = item.extract;
result2 = item.thumbnail.source;
result3 = item.content_urls.mobile.page;

return client.replyMessage(event.replyToken,[ {
    type: 'text',
    text: result1
    },
    {
    type: 'image',
    originalContentUrl: result2,
    previewImageUrl: result2
    },
    {
    type: 'text',
    text: result3
    }

自分で試したこと

console.log(item.thumbnail?.source);
    if (item.thumbnail?.source === undefined) {
    return Promise.resolve(null);

「?」を付けて、値がundefinedの時、nullとすると設定しましたが、
undefinedとターミナルに表示されるだけでした。LINEBotには何も返ってきませんでした。

どなたか教えてください。よろしくお願い致します!

0

1Answer

if (item.thumbnail?.source === undefined) {
    return Promise.resolve(null);
}

↑これは削除した上で、

result2 = item.thumbnail?.source;

↑この部分を

const result2 = item.thumbnail?.source ?? null;

とすればいいのではないでしょうか。

1Like

Comments

  1. コメントありがとうございます!! やってみたのですが同じくエラーです。。。。

    エラーの一部分ですが

    data: {
    message: 'The request body has 2 error(s)',
    details: [
    {
    message: 'May not be empty',
    property: 'messages[1].originalContentUrl'
    },
    {
    message: 'May not be empty',
    property: 'messages[1].previewImageUrl'
    }
    ]
    }
    },

    このような形です。もし他に良い案あれば、ぜひ教えて頂けますとありがたいです!

Your answer might help someone💌