Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / HTML

Quiz Application in Angular

4.82/5 (43 votes)
26 Jun 2019CPOL9 min read 178.6K   3.5K  
A general purpose quiz application in Angular (version 8) that can be used to run quizzes, mock tests, surveys, etc. This is an updated version for Quiz Application in AngularJs.

Introduction

Quiz application in one form or the other is becoming a general requirement for most of the applications these days. Be it Survey, mock test, preparation, self evaluation, gathering information, actual objective test or exam. This quiz application will help you to get through your need with minimal or no modification.

This article presents you a simplified way to create your quiz application in Angular 2 in just few lines of code. The quiz application accepts the questions in json format. So, you can easily send the json from the server in the pre-defined format and the Angular quiz application will render the quiz at the client side. The quiz also has review and display result section. If you wish to declare the result immediately, you can simply call another json with the answers in it and simply evaluate and display the results immediately. Alternatively, if you wish to just submit the answers to the server, you can also do so at onSubmit method quiz.component.ts.

If you are looking for quiz application in Angular 1.x, click here.

Background

This article is the updated version of Quiz Application in AngularJs. Since the technology has changed since the article was written, I may not continue updating major features in the previous version of this article. However, I will keep on adding features on this article.

This article assumes that you have the basic knowledge of Angular 2, bootstrap 4 and a bit of CSS. To run this article, you should know a bit on how to do npm install and run it using angular cli. Please visit Angular Cli if you wish to know how to run the application via angular cli command.

Using the Code

Using the code is simple. Just provide the json to the quiz application and it will render the quiz.

The json format should look like the following:

JavaScript
// aspnet.json
{
    "Id": 1,
    "name": "Asp.Net Quiz",
    "description": "Asp.Net Quiz (contains webform, mvc, web API, etc.)",
    "questions": [
        {
            "Id": 1010,
            "Name": "ASP.NET webform separates the HTML output from 
                     program logic using a feature named as",
            "QuestionTypeId": 1,
            "Options": [
                {
                    "Id": 1055,
                    "QuestionId": 1010,
                    "Name": "Exception",
                    "IsAnswer": false
                },
                {
                    "Id": 1056,
                    "QuestionId": 1010,
                    "Name": "Code-behind",
                    "IsAnswer": true
                },
                {
                    "Id": 1057,
                    "QuestionId": 1010,
                    "Name": "Code-front",
                    "IsAnswer": false
                },
                {
                    "Id": 1058,
                    "QuestionId": 1010,
                    "Name": "None of the above",
                    "IsAnswer": false
                }
            ],
            "QuestionType": {
                "Id": 1,
                "Name": "Multiple Choice",
                "IsActive": true
            }
        },
... [For full code, please see the sample attached.]

Note: You may not wish to include the IsAnswer property to the options as it might be an unsafe for a secured quiz. In such case, you can simply send the questions with IsAnswer. Once the user submits the quiz, onSubmit method in quiz.component.ts, you can call the questions with answers and evaluate the answers.

About Quiz Application

The quiz application consists of mainly 3 components/views: Quiz View, Review, Result. For the sake of simplicity, I have kept the views in the same file (The result view will be moved to a separate component soon). If you wish to scale this application, you can very well separate these views. Apart from this, quiz.component.ts has been used as a component class for all the views and styles.css has been used to apply CSS style to the application.

The Quiz Running Logic

The application has a small set of scripting part that has been handled by the controller: quiz.component.ts. First of all, the component loads the questions by using loadQuiz('data/aspnet.js') method called at ngOnInit event. The quiz questions should be provided in a pre-defined json format as mentioned in aspnet.json or other related json files present in data folder. Once the questions are loaded, user can answer the questions and the events are being captured by the same component. When user finally submits the quiz, you may submit the answers to the server in json format. Or load the questions with answers and evaluate the users answers to show the quiz result immediately. In the sample, I have provided the later approach for the sake of simplicity, but the first approach is also fairly simple.

The quiz.component.ts file looks like the following:

JavaScript
// quiz.component.ts
...
  ngOnInit() {
    this.quizes = this.quizService.getAll();
    this.quizName = this.quizes[0].id;
    this.loadQuiz(this.quizName);
  }

  loadQuiz(quizName: string) {
    this.quizService.get(quizName).subscribe(res => {
      this.quiz = res;
      this.pager.count = this.quiz.questions.length;
    });
  }

  get filteredQuestions() {
    return (this.quiz.questions) ?
      this.quiz.questions.slice(this.pager.index, this.pager.index + this.pager.size) : [];
  }

  onSelect(question: any, option: any) {
    if (question.QuestionTypeId == 1) {
      question.Options.forEach((x) => { if (x.Id != option.Id) x.Selected = false; });
    }

    if (this.config.autoMove) {
      this.goTo(this.pager.index + 1);
    }
  }

  goTo(index: number) {
    if (index >= 0 && index < this.pager.count) {
      this.pager.index = index;
      this.mode = 'quiz';
    }
  }
... 
[For full code, please see the sample attached.]

For now, I have used only one component. However, I will separate the result component to a separate component soon.

Quiz Configuration

The quiz configuration is an optional object that can be present in your <quiz>.json file. The config section allows you to customize your quiz the way you wish to do. The quiz application reads these configuration settings and applies these settings at the time of loading the quiz. The settings mainly consists of: shuffling the questions, showing/hiding pager, allowing back navigation, allowing auto move to next question. The details of this configuration is explained in "Quiz Features" section.

The quiz configuration looks like the following:

JavaScript
// csharp.json
...
    "config":{
        "shuffleQuestions": true,
        "showPager": false,
        "allowBack": true,
        "autoMove": true
    }
... 
[For full code, please see the sample attached.]

Services Used

For simplicity, I have used only one service in Angular2 component: quiz.service. It is used to retrieve quiz json file, populate the list of quizzes, and check the result.

Quiz View (HTML Template)

The Quiz View contains the UI for quiz questions, previous-next button, paging and related stuffs. I have chosen the structure of keeping one question per page but if you would like to show more than one question, you can simply change the pager.size value accordingly. For buttons and pagination UI, bootstrap has been used. The UI for questions and options has been set in styles.css.

The HTML for quiz view looks like the following:

HTML
// quiz.component.html
    <div *ngFor="let question of filteredQuestions;">
      <div class="badge badge-info">Question {{pager.index + 1}} of {{pager.count}}.</div>
      <h2>{{pager.index + 1}}. <span [innerHTML]="question.Name"></span></h2>
      <div class="row text-left options">
        <div class="col-md-6" *ngFor="let option of question.Options">
          <div class="option">
            <label class="" [attr.for]="option.Id">
                <input id="{{option.Id}}" type="checkbox" 
                [(ngModel)]="option.Selected" (change)="onSelect(question, option);" />
                {{option.Name}}
            </label>
          </div>
        </div>
      </div>
    </div>
... [For full code, please see the sample attached.]

If you know Angular 2, this part is simple to understand. To display the questions and options, *ngFor has been used.

The review and result view has also been implemented similarly by iterating over the quiz questions and displaying the needed stuff. Below is the screenshot of Review and Result View.

The quiz result view looks like the below image:

The Styling

For styling and theme, bootstrap 4 has been used. For further styling based on the applications need, CSS classes has been added in styles.css. I have tried my best to minimize the use of custom CSS, however, you may add as many custom CSS as you want. All the CSS styles are self-explanatory. If you wish to change the look and feel of the application, you can easily do so by changing the corresponding CSS class in styles.css. I have made all attempts to make it responsive so that the application can be navigated easily on mobile phones and tablets too.

Quiz Features

This section acts a small documentation kind of stuff for using the features of the quiz application.

Shuffle Questions

shuffleQuestions property in config section is used to mention whether the questions should be randomized before showing or not. If true, the questions will be randomized. The default value is false.

Shuffle Options

shuffleOptions property in config section is used to mention whether the options can be randomized before showing or not. If true, the questions will be randomized. The default value is false. This feature is configurable from the quiz json file.

Show Pager

showPager property in config section indicates whether to show the pager element in quiz or not. If false, the numeric pager will not be shown. In this case, the user can still navigate via. first, prev, next and last button. The default value is true.

Auto Move

autoMove property in config section indicates whether to move to next question automatically when the question is answered. If true, you don't need to press Next button to move to next question. The default value is false.

Load Quiz Dynamically

In mock test/practice exams, user might want to change the quiz dynamically. To do so, you just need to call loadQuiz method and pass the URL of the new quiz. The attached sample or the demo link illustrates this. (In the sample app, you can load the quiz dynamically via changing the drop-down at top right corner.)

HTML Questions

In many cases, you wish to have special characters, images, subscript, superscript, and other HTML elements. Adding HTML markup in question has been provided via angular sanitize. To add image or any HTML formatting in questions, just add the corresponding HTML tags in question.

I will keep on documenting other features as and when they will be available here.

Future Consideration

Due to time constraint, I could not implement other interesting features which might help you more if you wish to use this quiz application. I will add them later as and when I get time. I would also appreciate if someone can provide me the pull request in github, if they have implemented any of the pending features or existing features in a better way. :)

Some of the features I can think of are:

  • Quiz Options :In many cases, we need to randomize questions, randomize options, or set different marks for different questions. I am planning to provide these features which will be configurable from the quiz json file.
  • HTML Questions: In many cases, you wish to have special characters, subscript, superscript, and other html elements. So, in my opinion, providing html option in Quiz application would be a nice addition. This feature has been implemented.
  • Question Type: Currently, the application supports only multiple choice question. In many scenarios, it is needed to have multiple answer type question, true-false, etc. I will come up with this provision soon.
  • Timer :Timer is another important feature which every test/mock test wants to have. Timer/Stopwatch option shall also be provided as a configurable element in the quiz. Timer is now available in Quiz app.
  • Image for Question :Image is also one of the most needed feature in most of the quiz. I will come up with this feature in this article very soon. Image for questions can be provided by adding HTML questions.
  • Pick From Pool: In some scenarios, you might want to provide a pool of many questions as a json and want the Quiz application to randomly select n questions for the quiz. This feature will be implemented soon.
  • Optional Animation :Well, this is not an important feature but some people may want a bit of animation in his quiz application. I would, therefore, like to provide this feature as well.
  • Mobile Friendly: Even though this app is responsive and adjusts well with mobile and smaller screens, fonts and alignment needs to be adjusted according to the screen size. So, having a mobile friendly view is also a good and valid need. CSS has been optimized and css3 media query has been written to provide optimized view for mobile.
  • Tailored Questions :There are many cases when we require a tailored questions in a survey. This means that the next set of questions should come based on the option selected in current question of the survey. Based on email feedback from many users, I will give this feature a priority and will provide you as soon as I will get time for it.
  • Angular 2 version :Since Angular 2 is about to release, I would consider to re-write the application with better design and more flexibility in Angular 2.

Apart from the above features, if you feel some more feature should be added, please let me know. I will try my best to implement them.

History

  • 2017-01-26
    • First version release
  • 2017-03-05
    • Changed quiz to camel casing
    • Added strongly typed objects by adding models

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)