0

I'm trying to make a simple grammar quiz, but I'm having trouble figuring out how to sort array randomly while using ng-repeat. I would like to display both "Correct" sentence and "Incorrect" sentences and want them to be sorted in randomly.

You can check my code && data below:

(function(angular) {
  'use strict';

  angular.module('demo', ['ngAnimate'])
    .controller('repeatController', function($scope) {
      $scope.random = function() {
        return 0.5 - Math.random();
      };

      $scope.questions = {
        "0": {
          "Category": "Commas",
          "Correct": "Shirley Chisholm was the first major-party candidate to run for President in a major party. She ran as a Democrat.",
          "Given_sen": "\"Shirley Chisholm was the first major party candidate to run for President in a major party, she ran as a Democrat.\"",
          "Incorrect": [
            "\"Shirley Chisholm, the first major-party candidate to run for President in a major party, she ran as a Democrat.\"",
            "Shirley Chisholm was the first major-party candidate to run for President in a major party: she ran as a Democrat.",
            "Shirley Chisholm was the first major-party candidate to run for President in a major party (she ran as a Democrat)."
          ],
          "Question": "Fix the comma splice.",
          "Rule": "comma splice\n"
        },
        "1": {
          "Category": "Commas",
          "Correct": "Hattie McDaniel was the first African-American to win an Oscar. She won for her performance in Gone with the Wind.",
          "Given_sen": "\"Hattie McDaniel was the first African-American to win an Oscar, she won for her performance in Gone with the Wind.\"",
          "Incorrect": [
            "Hattie McDaniel was the first African-American to win an Oscar: she won for her performance in Gone with the Wind.",
            "\"Hattie McDaniel, the first African-American to win an Oscar, she won for her performance in Gone with the Wind.\"",
            "\"Hattie McDaniel was the first African-American to win an Oscar, for her performance in Gone with the Wind.\""
          ],
          "Question": "Fix the comma splice.",
          "Rule": "comma splice\n"
        }
      };
    });
})(window.angular);
<html>

<head>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js"></script>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular-animate.js"></script>
  <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
</head>

<body ng-app="demo">
  <div ng-controller="repeatController">
    <form ng-repeat="question in questions">
      <div class="well"><b> QUESTION: {{question.Question}}</b>
        <br> Category: {{question.Category}} </div>
      <div ng-repeat="incorrect_answer in question.Incorrect">
        <input type="radio" name="radio{{$parent.$index}}" value="{{incorrect_answer}}">{{incorrect_answer}}</input>
      </div>
      <div>
        <input type="radio">{{question.Correct}} </input>
      </div>
      <input type="submit" value="submit" />
    </form>
  </div>

</body>

</html>

Also if you can provide me the way to use "submit" button to find the correct answer, it would be wonderful! Right now, I am not sure how to find out the way to check whether the submitted answer is equal to "Correct" one.

Dylan Wheeler
  • 6,928
  • 14
  • 56
  • 80
Taehun Ahn
  • 49
  • 1
  • 6

3 Answers3

1

There are some mistakes:

  1. <input> is a self-closing tag;

  2. You forgot to call your function in your view like as below:

<div ng-repeat="incorrect_answer in random(question.Incorrect)">
  1. You have to return the array shuffled in your function:
$scope.random = function(array) {
  return array.sort(function() {
    return .5 - Math.random();
  });
}

(function(angular) {
  'use strict';
  
  angular.module('demo', [])
    .controller('repeatController', function($scope) {
      $scope.questions = {
        "0": {
          "Category": "Commas",
          "Correct": "Shirley Chisholm was the first major-party candidate to run for President in a major party. She ran as a Democrat.",
          "Given_sen": "\"Shirley Chisholm was the first major party candidate to run for President in a major party, she ran as a Democrat.\"",
          "Incorrect": [
            "\"Shirley Chisholm, the first major-party candidate to run for President in a major party, she ran as a Democrat.\"",
            "Shirley Chisholm was the first major-party candidate to run for President in a major party: she ran as a Democrat.",
            "Shirley Chisholm was the first major-party candidate to run for President in a major party (she ran as a Democrat)."
          ],
          "Question": "Fix the comma splice.",
          "Rule": "comma splice\n"
        },
        "1": {
          "Category": "Commas",
          "Correct": "Hattie McDaniel was the first African-American to win an Oscar. She won for her performance in Gone with the Wind.",
          "Given_sen": "\"Hattie McDaniel was the first African-American to win an Oscar, she won for her performance in Gone with the Wind.\"",
          "Incorrect": [
            "Hattie McDaniel was the first African-American to win an Oscar: she won for her performance in Gone with the Wind.",
            "\"Hattie McDaniel, the first African-American to win an Oscar, she won for her performance in Gone with the Wind.\"",
            "\"Hattie McDaniel was the first African-American to win an Oscar, for her performance in Gone with the Wind.\""
          ],
          "Question": "Fix the comma splice.",
          "Rule": "comma splice\n"
        }
      };

      function sort(array) {
        return array.sort(function() {
            return .5 - Math.random();
        });
      }

      function random() {
        for (var key in $scope.questions) {
          $scope.questions[key].Incorrect = sort($scope.questions[key].Incorrect);
        }
      }
      
      random();
    });
})(angular);
<!DOCTYPE html>
<html ng-app="demo">

<head>
  <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
  <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.7/angular.min.js"></script>
</head>

<body ng-controller="repeatController">
  <form ng-repeat="question in questions">
    <div class="col-md-12">
      <div class="well"><b> QUESTION: {{question.Question}}</b>
        <br> Category: {{question.Category}} </div>
      <div class="radio" ng-repeat="incorrect_answer in question.Incorrect">
        <label>
          <input type="radio" name="radio{{$parent.$index}}" value="{{incorrect_answer}}"> {{incorrect_answer}}
        </label>
      </div>
      <div class="form-group">
        <label class="radio-inline">
          <input type="radio"> {{question.Correct}}
        </label>
      </div>
      <div class="form-group">
        <input class="btn btn-primary" type="submit" value="Submit">
      </div>
    </div>
  </form>
</body>

</html>

EDIT:

  1. As pointed out by @charlietfl, it's better to loop over the whole object and shuffle the array once in controller to prevent digest problems.

  2. I think it's better to handle your items if you mix all questions (correct and incorrect) in an unique array.

developer033
  • 24,267
  • 8
  • 82
  • 108
  • Asking for serious problems with digests putting function in view that returns random sort. Should be sorted in controller and then passed to view – charlietfl Jul 19 '16 at 04:32
  • @charlietfl, I thought about this.. do you suggest to loop over all object and randomize all the incorrect questions once in controller? – developer033 Jul 19 '16 at 04:43
0

You can create a list of possible answers, shuffle the list and loop over them. You can also have a field for the correct answer. So instead of excluding the correct answer from the list, include them with the other ones and just shuffle it with an algorithm like knuth. So your model could look something like this:

$scope.model = {
  randomize: function (arr) {
    return knuthShuffle(arr.slice(0));
  },
  questions: [
    {
      id: 1,
      title: 'Title of the question',
      possibleAnswers: [{ name: 'Tom' }, { name: 'John' }, { name: 'Kim' }, { name: 'Tim' }],
      correctAnswer: { name: 'John' }
    }
  ]
};

and then in your view you could do something like:

<ul>
  <li ng-repeat="question in model.questions">
    <ul>
      <li ng-repeat="possibleAnswer in model.randomize(question.possibleAnswers)">
        {{possibleAnswer}}
      </li>
    </ul>
  </li>
</ul>

and to verify the answer you can have field to store the selected answer and pass it along to the backend:

selectedAnswer: {'name': 'John'}

the method on the controller would then call your service:

vm.verifyAnswer(model.selectedAnswer, correctAnswer)
AJ Meyghani
  • 4,389
  • 1
  • 31
  • 35
0

I think you have to create a array of possible answers and correct answer and use the randomize algorithams like https://github.com/coolaj86/knuth-shuffle

Or you can you method like specified in the below post.

ng-repeat changing sort order on all items when new item added to model

When you submit the data you can verify it in couple of ways.

  1. you can pass the value of selected radio button and question identifier if any or index of the question compare with the actual correct answer field in the questions array.
  2. You can store the question identifier and selected answer and send it to the server to verify.

I hope it helps you.

Community
  • 1
  • 1
Ramu Achala
  • 161
  • 1
  • 5