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

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

ただいまの
回答率

88.20%

外部APIで取得したオブジェクトからDOMでボタンを作成し、ランダムな選択肢を表示したい

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 388

mt-0509

score 9

前提・実現したいこと

外部APIで取得した値を使って、4択から答えを選ぶクイズアプリを自作しています。

正解のオブジェクトと不正解のオブジェクトの2つのオブジェクトから値を取得し、DOMで作成したボタンに重複しないランダムな選択肢を表示させたいです。

シャッフルアルゴリズムとforEachを使うのはわかったのですが、
①forEachから値を取り出すための配列に何を入れていいのかが分からない
②forEach内でどのように表示するのかが分からない

自分なりにコードを書いてみましたが、不明なため教えて下さい。
説明の仕方が下手で申し訳ありませんが、よろしくお願い致します。

※追記
correct_answer、incorrect_answersの中身は外部APIからランダムで問題を取得しているため、都度変わります。

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

エラーメッセージ

該当のソースコード

'use strict';

{
  // 開始ボタンを押したらスタートする
  document.getElementById('start').addEventListener('click', () => {
    document.getElementById('question').innerHTML = '少々お待ちください';

      // 最初に非同期処理を行う
      function quiz() {
        return new Promise(function (resolve, reject) {
          // setTimeout(function () {
          //   resolve(console.log('非同期成功'));
          // }, 5000);
        });
      }

      quiz();

    const DATA_URL = 'https://opentdb.com/api.php?amount=10';
    fetch(DATA_URL)
    .then(function(response) {
      return response.json();
    })
    .then(function(jsonDATA) {

      var obj = jsonDATA;

      console.log(jsonDATA);

      // 回答ボタンを追加
      let btnone = document.createElement('button');
      let btntwo = document.createElement('button');
      let btnthree = document.createElement('button');
      let btnfour = document.createElement('button');

      document.getElementById('answer-one').appendChild(btnone);
      btnone.innerHTML = obj.results[0].correct_answer;

      document.getElementById('answer-two').appendChild(btntwo);
      btntwo.innerHTML = obj.results[0].incorrect_answers[0];

      document.getElementById('answer-three').appendChild(btnthree);
      btnthree.innerHTML = obj.results[0].incorrect_answers[1];

      document.getElementById('answer-four').appendChild(btnfour);
      btnfour.innerHTML = obj.results[0].incorrect_answers[2];




      var x = correct_answer[0];
      var y = incorrect_answers[0];
      var z = incorrect_answers[1];
      var v = incorrect_answers[2];


      // ランダムに使う配列
      var arr = [x, y, z, v];
      var a = arr.length;

      // シャッフルアルゴリズム
      while (a) {
        var j = Math.floor( Math.random() * a );
        var t = arr[--a];
        arr[a] = arr[j];
        arr[j] = t;
      }

      // シャッフルされた配列の要素を順番に表示する
      arr.forEach( function (value) {
        btnone.innerHTML = obj.results[0].value
        btntwo.innerHTML =obj.results[0].value
        btnthree.innerHTML =obj.results[0].value
        btnfour.innerHTML =obj.results[0].value
      });


      // 取得したデータを表示する
      // 問題文
      document.getElementById('question').innerHTML = obj.results[0].question;

      // カテゴリー
      document.getElementById('category').innerHTML = obj.results[0].category;

      // 難易度
      document.getElementById('difficulty').innerHTML = obj.results[0].difficulty;

    });
  })
}

試したこと

ここに問題に対して試したことを記載してください。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • mt-0509

    2020/03/25 20:04

    外部APIの中身がjsonデータになっていて、jsonデータ内でcorrect_answerなどが使われていました。
    なのでそのまま使っています。

    もし質問の意図をよく理解できていなかったら申し訳ないです。

    一応コードを全文表示させて頂きました。

    キャンセル

  • Lhankor_Mhy

    2020/03/25 20:10

    なるほど。
    では、中身が入っていないことにはお気づきではないのですね。では、そこから回答させていただきます。

    キャンセル

  • mt-0509

    2020/03/25 20:15

    お手数おかけしますが、よろしくお願い致します。

    キャンセル

回答 1

checkベストアンサー

+2

ご提示のコードを実行してみましたが、correct_answer is not definedというエラーが発生しました。

これは、

      var x = correct_answer[0];
      var y = incorrect_answers[0];
      var z = incorrect_answers[1];
      var v = incorrect_answers[2];

↑の部分で使われている、correct_answer incorrect_answersが定義されていないからです。

おそらく、mt-0509さんの気持ちとしては、obj.results[0].correct_answerのつもりでお書きになったのだと思いますが、これは省略してはいけないものです。ひとまず、この部分をきちんと書いてみるところからお始めになってはいかがでしょうか。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/03/25 21:49

    回答ありがとうございます。
    教えて頂いたようにやってみてまたコード書いてみます。

    キャンセル

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

  • ただいまの回答率 88.20%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る