5

I'm creating a quiz and every time I start the quiz I want to shuffle the questions, so that they won't appear in the same order every time.

I have this in my html code:

<div ng-repeat="question in questions | filter:ids | orderBy:randomSort">
    <div id="question">{{question.question}}</div><img id="nextImg" ng-src="../app/img/next.png" ng-click="next()" />
    <img class="quizImg" ng-hide="{{question.image}}==null" ng-src="{{question.image}}" />

    <div class="answer" ng-repeat="answer in question.answers">
        <input type="radio" ng-click="checked(answer)">{{answer.answer}}
    </div>
    <!--input id="nextQuestion" type="button" ng-click="next()" value="{{buttonText}}"-->
</div>

and this in my controller

 lycheeControllers.controller('quizCtrl', ['$scope', '$http', function ($scope, $http) {
    $http.get('json/questions.json').success(function (data) {
        //all questions
        $scope.questions = data;

        $scope.titel = "Check your knowledge about lychees"


        $scope.randomSort = function(question) {
                      return Math.random();
                    };

        //filter for getting answers / question
        $scope.ids = function (question) {
            return question.id == number;
        }

        $scope.find = function (id) {
            if (id == number) {
                return true;
            }
        }


        $scope.next = function () {
            if (!(number == (data.length))) {
                //questionId++;
                number++;
                if (correct == true) {
                    points++;
                }
                //alert(points);
            } else {
                if (!end) {
                    if (correct == true) {
                        points++;
                        end = true;
                    }
                }

                alert("Quiz finished: your total score is: " + points);
            }
            correct = false;
        }

        $scope.checked = function (answer) {
            //alert(answer.answer);

            if (answer.correct == "yes") {
                correct = true;
            } else {
                correct = false;
            }

            //alert(correct);
        }


    });

}])
;

unfortunately this isn't working at all..

4
  • Not working at all is a bit vague. Can you be more specific, and post a minimal Plunker that contains just enough code to show your issue? Commented Dec 26, 2013 at 18:30
  • Your scope function works fine in my simple case: jsfiddle.net/A8Eg2 Click Run couple times to get different results. Commented Dec 26, 2013 at 18:31
  • It gives me the same result every time... Commented Dec 26, 2013 at 18:34
  • random sort function needs better approach, not hard to find random sort methods in a web search....lots of them on this site for sure Commented Dec 26, 2013 at 20:24

3 Answers 3

26

Thx to http://bost.ocks.org/mike/shuffle/ use this shuffling function:

Speciality with it is, that the input array stays bindable because the shuffling wont create a new array but instead does the shuffling on the same reference.

// -> Fisher–Yates shuffle algorithm
var shuffleArray = function(array) {
  var m = array.length, t, i;

  // While there remain elements to shuffle
  while (m) {
    // Pick a remaining element…
    i = Math.floor(Math.random() * m--);

    // And swap it with the current element.
    t = array[m];
    array[m] = array[i];
    array[i] = t;
  }

  return array;
}

side note: lodash's _.shuffle(array) does not work either because they are creating a new array which breaks binding (so a shuffled array won't trigger the model to be dirty)


To complete the answer to a working solution, following steps should do it:

  • copy the function so you can use it inside your controller.
  • call it in your $http result callback:
$http.get('json/questions.json').success(function (data) {
  //all questions
  $scope.questions = data;

  shuffleArray($scope.questions);

  ...
}
Sign up to request clarification or add additional context in comments.

Comments

2

Use Lodash

_.shuffle(collection)

1 Comment

Yes, I solved this type of problem using lodash _.shuffle() method. It's easy to use and very simple. link
0

I used lodash _.shuffle() for showing products in home page randomly. It's very simple to use like below:

In home.component.ts file,

products: IProduct[] = [];

  constructor(private productService: ProductService) {}

  ngOnInit(): void {
    this.productService
      .getProducts()
      .subscribe((prodData: IProductsResponse) => {
        this.products = _.shuffle(prodData.products);
        console.log(this.products);
      });
  }

In home.component.html file,

<div class="col-md-4 col-sm-6" *ngFor="let product of products let idx = index">
            <div class="card my-2" *ngIf="idx <= 8">
                <img
                  [src]="product.image"
                  alt="{{ product.title }}"
                  width="200px"
                  height="300px"
                  class="card-img-top"
                  style="cursor: pointer"
                  (click)="selectProduct(product._id)"
                />
                <div class="card-header">
                  <div class="card-title">
                    <p>{{ product.title.substr(0, 50) | uppercase }}</p>
                  </div>
                </div>
         </div>
 </div>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.