##前提・実現したいこと
JavaScriptとHTMLを使った10回クイズの問題を作ってい流のですがその際のエラーハンドリング
を行いたいのですがうまくいきません。
- クイズデータ取得時は非同期処理を走らせ、「取得中」の画面が表示される
- クイズは10問出題される
- 各クイズは、出題文、ジャンル、難易度が表示される
- クイズ終了後は正答数が表示される
##該当のソースコード
JavaScript
1{ 2 const API_URL = 'https://opentdb.com/api.php?amount=10'; 3 4 class Quiz { 5 constructor(quizData) { 6 this._quizzes = quizData.results; 7 this._correctAnswersNum = 0; 8 } 9 10 getQuizCategory(index) { 11 return this._quizzes[index - 1].category; 12 } 13 14 getQuizDifficulty(index) { 15 return this._quizzes[index - 1].difficulty; 16 } 17 18 getNumOfQuiz() { 19 return this._quizzes.length; 20 } 21 22 getQuizQuestion(index) { 23 return this._quizzes[index - 1].question; 24 } 25 26 getCorrectAnswer(index) { 27 return this._quizzes[index - 1].correct_answer; 28 } 29 30 getIncorrectAnswers(index) { 31 return this._quizzes[index - 1].incorrect_answers; 32 } 33 34 countCorrectAnswersNum(index, answer) { 35 const correctAnswer = this._quizzes[index - 1].correct_answer; 36 if (answer === correctAnswer) { 37 return this._correctAnswersNum++; 38 } 39 } 40 41 getCorrectAnswersNum() { 42 return this._correctAnswersNum; 43 } 44 } 45 46 const titleElement = document.getElementById('title'); 47 const questionElement = document.getElementById('question'); 48 const answersContainer = document.getElementById('answers'); 49 const startButton = document.getElementById('start-button'); 50 const genreElement = document.getElementById('genre'); 51 const difficultyElement = document.getElementById('difficulty'); 52 53 startButton.addEventListener('click', () => { 54 startButton.hidden = true; 55 fetchQuizData(1); 56 }); 57 58 const fetchQuizData = async (index) => { 59 titleElement.textContent = '取得中'; 60 questionElement.textContent = '少々お待ち下さい'; 61 62 63 const response = await fetch(API_URL); 64 const quizData = await response.json(); 65 const quizInstance = new Quiz(quizData); 66 setNextQuiz(quizInstance, index); 67 }; 68 69 const setNextQuiz = (quizInstance, index) => { 70 while (answersContainer.firstChild) { 71 answersContainer.removeChild(answersContainer.firstChild); 72 } 73 74 if (index <= quizInstance.getNumOfQuiz()) { 75 makeQuiz(quizInstance, index); 76 } else { 77 finishQuiz(quizInstance); 78 } 79 }; 80 81 const makeQuiz = (quizInstance, index) => { 82 titleElement.innerHTML = `問題 ${index}`; 83 genreElement.innerHTML = `【ジャンル】 ${quizInstance.getQuizCategory(index)}`; 84 difficultyElement.innerHTML = `【難易度】 ${quizInstance.getQuizDifficulty(index)}`; 85 questionElement.innerHTML = `【クイズ】${quizInstance.getQuizQuestion(index)}`; 86 87 const answers = buildAnswers(quizInstance, index); 88 89 answers.forEach((answer) => { 90 const answerElement = document.createElement('li'); 91 answersContainer.appendChild(answerElement); 92 93 const buttonElement = document.createElement('button'); 94 buttonElement.innerHTML = answer; 95 answerElement.appendChild(buttonElement); 96 97 buttonElement.addEventListener('click', () => { 98 quizInstance.countCorrectAnswersNum(index, answer); 99 index++; 100 setNextQuiz(quizInstance, index); 101 }); 102 }); 103 }; 104 105 const finishQuiz = (quizInstance) => { 106 titleElement.textContent = `あなたの正答数は${quizInstance.getCorrectAnswersNum()}です` 107 genreElement.textContent = ''; 108 difficultyElement.textContent = ''; 109 questionElement.textContent = '再チャレンジしたい場合は下をクリック'; 110 111 const restartButton = document.createElement('button'); 112 restartButton.textContent = 'ホームに戻る'; 113 answersContainer.appendChild(restartButton); 114 restartButton.addEventListener('click', () => { 115 location.reload(); 116 }); 117 }; 118 119 const buildAnswers = (quizInstance, index) => { 120 const answers = [ 121 quizInstance.getCorrectAnswer(index), 122 ...quizInstance.getIncorrectAnswers(index) 123 ]; 124 return shuffleArray(answers); 125 }; 126 127 const shuffleArray = ([...array]) => { 128 for (let i = array.length - 1; i >= 0; i--) { 129 const j = Math.floor(Math.random() * (i + 1)); 130 [array[i], array[j]] = [array[j], array[i]]; 131 } 132 return array; 133 }; 134 }
HTML
1<!DOCTYPE html> 2<html lang="en"> 3<head> 4 <meta charset="UTF-8"> 5 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 7 <title>Document</title> 8</head> 9<body> 10 <div class="container"></div> 11 <h1 id="title">ようこそ</h1> 12 <h4 id="genre"></h4> 13 <h4 id="difficulty"></h4> 14 <p id="question"><hr>以下のボタンをクリック<hr></p> 15 <button id="start-button">開始</button> 16 </div> 17 <div id="answers"></div> 18<script src="app.js"></script> 19</body> 20</html>
##エラーハンドリングをしたいと思われる箇所
const response = await fetch(API_URL); const quizData = await response.json(); const quizInstance = new Quiz(quizData);
##試したこと
以下のコードのように成功時のコードを記述の欄にそのま該当コード
を記述してみましたがう甘く作動しませんでした。
JavaScript
1fetch(API_URL, { 2 method: 'GET' 3 }) 4 .then(response => { 5 if (!response.ok) { 6 console.error('サーバーエラー'); 7 } 8 //成功時のコードを記述 9 const response = await fetch(API_URL); 10 const quizData = await response.json(); 11 const quizInstance = new Quiz(quizData); 12 }) 13 .catch(error => { 14 console.error('通信に失敗しました', error); 15 });
また新しくコードを書いてみましたが何も変化が起きず成功したいるのか、
分かりません。
JavaScript
1 const quizInstance = new Quiz(quizData); 2 fetch('https://opentdb.com/api.php?amount=10') 3 .then((response) => response.text()) 4 .then((text) => console.log(text)) 5 .catch((error) => console.log(error)); 6 fetch('file.txt') 7 .then((response) => { 8 if(response.ok) { // ステータスがokならば 9 return response.text(); // レスポンスをテキストとして変換する 10 } else { 11 throw new Error(); 12 } 13 }) 14 .then((text) => console.log(text)) 15 .catch((error) => console.log(error));
宜しくお願いします。
あなたの回答
tips
プレビュー