Welcome to the Treehouse Community

The Treehouse Community is a meeting place for developers, designers, and programmers of all backgrounds and skill levels to get support. Collaborate here on code errors or bugs that you need feedback on, or asking for an extra set of eyes on your latest project. Join thousands of Treehouse students and alumni in the community today. (Note: Only Treehouse students can comment or ask questions, but non-students are welcome to browse our conversations.)

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and a supportive community. Start your free trial today.

JavaScript Object-Oriented JavaScript (2015) Practice Project Project Overview

Peter Csakany
Peter Csakany
3,925 Points

My Solution

Well it's not really a question but I have seen others showing their solution for this task so I thought I can share mine as well,

I went for a slightly different approach as I was lazy to make new questions therefore I got a json file with random questions to use. With it I could practice a little ajax and JQuery as well along the way, I wasn't sure if we should use prototypical inheritance but I didn't see an opportunity in this project where it could be implemented.

app.js

let quiz = new Quiz();

quiz.loadRandomQuestions();
$(document).ajaxSuccess(function () {
   renderQuestion(quiz.getCurrentQuestion());
   renderQuestionNumber(quiz.currentQuestionIndex + 1, quiz.questions.length);
});


$(document).on('click','button',function () {
    let btn = $('#' + this.id);
    let p = btn.prev();
    if(p.text() === quiz.getCurrentQuestion().correctAnswer){
        quiz.score ++;
    }
    quiz.nextQuestion();
    if(!quiz.endGame){
        clearQuiz();
        renderQuestion(quiz.getCurrentQuestion());
        renderQuestionNumber(quiz.currentQuestionIndex + 1, quiz.questions.length);
    }
    else{
        renderEndGame(quiz.score);
    }
});

quiz.js

function Quiz() {
    this.questions = [];
    this.currentQuestionIndex = 0;
    this.score = 0;
    this.endGame = false;
}

Quiz.prototype.add = function (question) {
    this.questions.push(question);
};

Quiz.prototype.getCurrentQuestion = function () {
  return this.questions[this.currentQuestionIndex];
};

Quiz.prototype.loadRandomQuestions = function () {
    let questions = [];
    $.getJSON('questions.json', {
        format: 'json'
    }, function (data) {
        if(data.response_code === 0){
            $.each(data.results, function (i, item) {
                let question = new Question(item.question, item.incorrect_answers, item.correct_answer);
                question.answers.push(question.correctAnswer);
                question.answers = question.shuffle(question.answers);
                questions.push(question);
            })
        }
    }); // end getJSON
    this.questions = questions;
};

Quiz.prototype.nextQuestion = function () {
    if(this.currentQuestionIndex < this.questions.length - 1){
        this.currentQuestionIndex ++;
    }
    else
    {
        this.endGame = true;
    }
};

question.js

function Question(title, answers, correctAnswer) {
    this.title = title;
    this.answers = answers;
    this.correctAnswer = correctAnswer;
}

Question.prototype.shuffle = function (answers) {
    for (let i = answers.length - 1; i > 0; i--) {
        let j = Math.floor(Math.random() * (i + 1));
        let temp = answers[i];
        answers[i] = answers[j];
        answers[j] = temp;
    }
    return answers;
};

quiz_ui,js

let qst = $('#question');
let score = $('#score');
let progress = $('#progress');

function renderQuestion (question){
    qst.text(question.title);
    $.each(question.answers,function (i,answer) {
        score.append('<p id="choice' + i + '">'+answer+'</p>');
        score.append('<button id="guess' + i +'" class="btn--default">Select Answer</button>');
    })
}

function renderQuestionNumber(x, y) {
    progress.text('Question ' + x + ' of ' + y);
}

function clearQuiz() {
    qst.text('');
    progress.text('');
    $('h3 > p').remove();
    $('h3 > button').remove();
}

function renderEndGame(scorePoints) {
    clearQuiz();
    qst.text('Game Over!');
    score.text('Your score: ' + scorePoints);
}

I will definitely work on it in the future. It was quite a challenge to make it from scratch.

p.s.: I got the json file with the questions from: https://opentdb.com/api_config.php

1 Answer

Steven Parker
Steven Parker
218,691 Points

I love that question resource! Great find! :+1: A few suggestions came to mind:

  • with a slight modification you could draw the questions directly from the API
  • then you could add a "start" screen where you allow the player to choose category and/or difficulty
  • you could also choose the number of questions
  • you could also choose a number of players, get names, give alternating turns, and keep separate scores

I was going to try out the program but it requires HTML and CSS components as well that were not provided (and currently the data file). You could share the entire project if you, make a snapshot of your workspace and post the link to it here.

Peter Csakany
Peter Csakany
3,925 Points

Thank you Steven for the feedback! I will apply some of your suggestions. I don't use workspaces as I prefer to work with local files and use my fav IDE but you can find all the files here: Link

Due to the ajax call it requires a server to run. I use MAMP on my computer for that. Checking up on the api for the questions I saw a few handy options like fetching the categories and the number of available questions in a category. I will try to come up with a form at the start of quiz where the player can choose from options although I'm not really good with css formatting. :D

Steven Parker
Steven Parker
218,691 Points

If you apply my first suggestion, you no longer need your own server as it will draw the questions from the API directly:

//  $.getJSON('questions.json', {                         // just change this line ...
    $.getJSON('https://opentdb.com/api.php?amount=10', {  // ... to this

I did try it out, very nice! And I saw one other change needed to render the special characters properly from the API:

//  qst.text(question.title);    // change this line ...
    qst.html(question.title);    // ... to this