0

I am trying to push a shuffled string array to my scope variable, but some how its throwing error for duplicate array values. This never happened before.

Below is my code snippet. You can check the console for error:

var app = angular.module('ABCD', []);
app.controller('ABCDController', ['$scope',
  function($scope) {
    $scope.start_word = ['C', 'A', 'T'];
    $scope.word = [
      ['C', 'A', 'T']
    ];
    $scope.shuffle = function() {
      var shuffle_word = Shuffle($scope.word[0]);
      console.log("SHUFFLED VARIABLE: " + shuffle_word);
      console.log("SCOPE VARIABLE: " + $scope.word);
      $scope.word.push(shuffle_word);
    };
  }
]);

function Shuffle(o) {
  for (var j, x, i = o.length; i; j = parseInt(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
  return o;
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.9/angular.min.js"></script>
<div ng-app="ABCD">
  <div ng-controller="ABCDController">
    <button class="btn btn-primary" ng-click="shuffle()">Shuffle</button>
    <p>START WORD: {{start_word}}</p>
    <p ng-repeat="(key,value) in word">SHUFFLED WORD: {{value}}</p>
  </div>
</div>

My error is, when I try to push new shuffled value into the array, it changes all values to the new. For eg:

Initial array:

console.log($scope.word); OUTPUT: [['C','A','T']]

After push:

console.log($scope.word) OUTPUT: [['T','C','T'],['T','C','T']]

5
  • ng-repeat="(key, val) in x" is the syntax for objects.. you want ng-repeat="letter in word" for arrays. Commented Mar 2, 2015 at 17:49
  • My problem is when I try to push my shuffled value in the array, it changes the previous one, because of which I am getting duplicate error Commented Mar 2, 2015 at 17:51
  • So do you want a history of entirely new shuffled words for each time you click Shuffle? Or only the most recent result? Commented Mar 2, 2015 at 17:52
  • 1
    Add a track by clause: ng-repeat="letter in word track by $index" Commented Mar 2, 2015 at 17:53
  • I only want newly added value to be changed, in my case entire scope array is getting changed. Please refer my question again. I edited it with more description Commented Mar 2, 2015 at 17:55

3 Answers 3

3

You're shuffling the original word and creating two values that are the same. Use a temporary copy of the word as shown below. Edit: This answer shows the trick of copying an array.

var app = angular.module('ABCD', []);
app.controller('ABCDController', ['$scope',
  function($scope) {
    $scope.start_word = ['C', 'A', 'T'];
    $scope.word = [
      ['C', 'A', 'T']
    ];
    $scope.shuffle = function() {
      var tmpWord = $scope.word[0].slice(); // create a copy
      var shuffle_word = Shuffle(tmpWord);
      console.log("SHUFFLED VARIABLE: " + shuffle_word);
      console.log("SCOPE VARIABLE: " + $scope.word);
      $scope.word.push(shuffle_word);
      console.log($scope.word);
    };
  }
]);

function Shuffle(o) {
  for (var j, x, i = o.length; i; j = parseInt(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
  return o;
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.9/angular.min.js"></script>
<div ng-app="ABCD">
  <div ng-controller="ABCDController">
    <button class="btn btn-primary" ng-click="shuffle()">Shuffle</button>
    <p>START WORD: {{start_word}}</p>
    <p ng-repeat="(key,value) in word">SHUFFLED WORD: {{value}}</p>
  </div>
</div>

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

1 Comment

This worked, but how slice() helped me here? I didnt get that part
0

You never reset your word array, so each new call to Shuffle() is adding onto the array instead of just replacing the contents of the array.

$scope.shuffle = function() {
  var shuffle_word = Shuffle($scope.word[0]);
  console.log("SHUFFLED VARIABLE: " + shuffle_word);
  console.log("SCOPE VARIABLE: " + $scope.word);
  $scope.word = []; //clear the previous array elements
  $scope.word.push(shuffle_word);
};

Or a a complete snippet (note I changed the word to "catalog").

var app = angular.module('ABCD', []);
app.controller('ABCDController', ['$scope',
  function($scope) {
    $scope.start_word = ['C', 'A', 'T', 'A', 'L', 'O', 'G'];
    $scope.word = [
      ['C', 'A', 'T', 'A', 'L', 'O', 'G']
    ];
    $scope.shuffle = function() {
      var shuffle_word = Shuffle($scope.word[0]);
      console.log("SHUFFLED VARIABLE: " + shuffle_word);
      console.log("SCOPE VARIABLE: " + $scope.word);
      $scope.word = []; //clear the previous array elements
      $scope.word.push(shuffle_word);
    };
  }
]);

function Shuffle(o) {
  for (var j, x, i = o.length; i; j = parseInt(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
  return o;
}
  
<!DOCTYPE html>
<html ng-app="ABCD">

  <head>
    <meta charset="utf-8" />
    <title>AngularJS Plunker</title>
    <script>document.write('<base href="' + document.location + '" />');</script>
    <link rel="stylesheet" href="style.css" />
    <script data-require="[email protected]" src="https://code.angularjs.org/1.3.14/angular.js" data-semver="1.3.14"></script>
    <script src="app.js"></script>
  </head>

<div ng-app="ABCD">
  <div ng-controller="ABCDController">
    <button class="btn btn-primary" ng-click="shuffle()">Shuffle</button>
    <p>START WORD: {{start_word}}</p>
    <p ng-repeat="(key,value) in word ">SHUFFLED WORD: {{value}}</p>
  </div>
</div>

</html>

Comments

0

Perhaps try have a word object within the word array something like:

$scope.word[{num:0,word:'CAT'},{num:1,word:'ACT'}];

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.