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']]

Niraj Chauhan
  • 7,677
  • 12
  • 46
  • 78
  • `ng-repeat="(key, val) in x"` is the syntax for objects.. you want `ng-repeat="letter in word"` for arrays. – tymeJV Mar 02 '15 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 – Niraj Chauhan Mar 02 '15 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? – ryanyuyu Mar 02 '15 at 17:52
  • 1
    Add a `track by` clause: `ng-repeat="letter in word track by $index"` – tymeJV Mar 02 '15 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 – Niraj Chauhan Mar 02 '15 at 17:55

3 Answers3

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>
Community
  • 1
  • 1
camden_kid
  • 12,591
  • 11
  • 52
  • 88
0

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

$scope.word[{num:0,word:'CAT'},{num:1,word:'ACT'}];
Kromster
  • 7,181
  • 7
  • 63
  • 111
helen
  • 1
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="angular.js@1.3.x" 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>
ryanyuyu
  • 6,366
  • 10
  • 48
  • 53