1

I'm having issues with my randomWidth() function calling twice, even when I remove the ng-repeat attribute from my element it still calls twice. I can't seem to figure out how to get around this issue. I'm guessing there's a way around this or maybe something obviously I'm leaving out?

HTML:

<div id="body-wrapper" ng-app="gallery" ng-controller="mainCtrl">
<section id="sidebar">

  <h1>Gallery</h1>

</section>

<main>
  <div class="box" ng-repeat="img in imgs" ng-style="{'width': randomWidth()}">
    <div class="box-wrapper"></div>
  </div>
</main>
</div>

Javascript:

angular.module('gallery', [])
.controller('mainCtrl', function($scope){

  $scope.imgs = [
    {
      title: 'image1'
    },
    {
      title: 'image2'
    },
    {
      title: 'image3'
    },
    {
      title: 'image4'
    },
    {
      title: 'image5'
    },
    {
      title: 'image6'
    }
  ];

  $scope.randomWidth = function(){
    const widths = ['25%', '33%', '40%', '50%'];
    const max = widths.length;
    const min = 0;
    var r = Math.floor(Math.random() * (max - min)) + min;
    console.log(widths[r]);
    return widths[r];
  }
})

live code: http://codepen.io/daviddiefenderfer/pen/qZpqdK

  • what is telling you it's being called twice? I am not seeing any obvious indication that randomWidth is getting called twice. Did you do a hard refresh? – Ji_in_coding Apr 07 '16 at 16:09
  • 1
    I think tt will be called on each digest loop - Take a look at the errors in the console. – Alon Eitan Apr 07 '16 at 16:10
  • As Alon says, you are incorrectly assuming that `ng-style` will evaluate `randomWidth()` only once. This is not the case. `ng-style` will reevaluate it whenever there is reason to suspect that the resulting value might have changed. You should precompute the random widths and assign them as properties on `$scope` if you want them to be fixed. – Oliver Apr 07 '16 at 16:14
  • I get Error: [$rootScope:infdig] and in the console logs there's 12 widths logged when there should only be 6 – David Diefenderfer Apr 07 '16 at 16:15
  • may be help you http://stackoverflow.com/questions/21586369/random-orderby-in-angularjs-1-2-returns-infdig-errors/21587316#21587316 – Hadi J Apr 07 '16 at 16:18
  • No, I definitely want randomWidth() to run for each instance of img, which in this case is 6, but for some reason i'm getting 12 outputs and when I remove ng-repeat it still runs twice. – David Diefenderfer Apr 07 '16 at 16:19

2 Answers2

3

See this updated codepen - you need to call randomWidth in your JS, once per image. The way you have it set up, it's called the first time, which end up modifying your element, which triggers a digest cycle, which triggers another call to randomWidth, etc, etc until Angular stops you becasue it detects the infinite loop.

http://codepen.io/lwalden/pen/KzZWXK

Change to HTML:

<div class="box" ng-repeat="img in imgs" ng-style="{'width': img.style}">

Change to JS:

angular.module('gallery', [])
.controller('mainCtrl', function($scope){

  $scope.randomWidth = function(){
    const widths = ['25%', '33%', '40%', '50%'];
    const max = widths.length;
    const min = 0;
    var r = Math.floor(Math.random() * (max - min)) + min;
    console.log(widths[r]);
    return widths[r];
  }

  $scope.imgs = [
    {
      title: 'image1',
      style: $scope.randomWidth()
    },
    {
      title: 'image2',
      style: $scope.randomWidth()
    },
    {
      title: 'image3',
      style: $scope.randomWidth()
    },
    {
      title: 'image4',
      style: $scope.randomWidth()
    },
    {
      title: 'image5',
      style: $scope.randomWidth()
    },
    {
      title: 'image6',
      style: $scope.randomWidth()
    }
  ];
})
lwalden
  • 813
  • 7
  • 11
1

I think this question has been sufficiently answered already.

I would suggest taking a look at this article on $digest.

Note: At a minimum, $digest will run twice even if your listener functions don’t change any models. As discussed above, it runs once more to make sure the models are stable and there are no changes.

Community
  • 1
  • 1
Forest Toney
  • 48
  • 1
  • 4
  • As an aside, the `infdig` error show in the code example means that there is infinite digests - because with random results of `randomWidth()`, two subsequent digests are never stable. – Oliver Apr 07 '16 at 16:24
  • Thank you for the link to this article, makes sense why It was running the function twice now. – David Diefenderfer Apr 07 '16 at 16:29