0

I'm looping a number (from 0 to 7) to get the index of the next day.
Here bellow is a fiddle working.

The problem is the first day is not "Monday", but Friday. So, the number is not 0 but 4...

I do not understand where is the problem.
Please help

(function(){
 
 var app = angular.module('myApp', [ ]);

 app.controller('CalenderController', function(){
  this.firstDay = -1;
        
        this.getDayName = function(){
   this.firstDay++;
   if(this.firstDay ==  7){
    this.firstDay = 0;
   }
   return dayNames[this.firstDay];
  };
        
        this.dayLength = function(){
            return new Array(13);
        }
 });

 //Variables 
 var dayNames = ['Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa', 'So'];

})();
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular.min.js"></script>
<div class="container" ng-app="myApp" ng-controller="CalenderController as calender">
     <div ng-repeat="item in calender.dayLength() track by $index">
         {{calender.getDayName()}}
     </div>
</div>
Cœur
  • 37,241
  • 25
  • 195
  • 267
gr3g
  • 2,866
  • 5
  • 28
  • 52
  • Please don't ask the same question multiple times; The answer to the last question you asked on the same topic gave almost identical answers to this. – Claies Feb 21 '15 at 23:16
  • I had to repost a easier way to explain the problem. Previous question will be deleted – gr3g Feb 21 '15 at 23:18

1 Answers1

1

It is a very bad idea to leave side-effects in functions that are being watched by Angular. Any function that is called from within an expression {{something()}} will be evaluated on every digest cycle, and so, these functions must be idempotent.

The getDayName function is not idempotent, because it changes this.firstDay.

Not only that, but it also returns a different value every time it's called, and so it causes the digest cycle to re-run (until it's aborted by Angular after 10 iterations).

Instead, use the $index directly to access the dayName array:

<div ng-repeat="item in calendar.dayLength()">
  {{calendar.dayNames[$index % 7]}}
</div>

and expose dayNames as a VM with this.dayNames.

EDIT: On second thought, it's better to expose this as a function, so that you could do mod 7 there:

$scope.getDayName = function(dayIndex){
   return dayNames[dayIndex % 7];
}

and in the View:

{{calendar.getDayName($index)}}

EDIT 2: If you don't need to have a flat DOM hierarchy of <div>s for all the days over 2 weeks, you could even do this much simpler:

<div ng-repeat="week in [0, 1]">
  <div ng-repeat="day in dayNames">
    {{day}}
  </div>
</div>
Community
  • 1
  • 1
New Dev
  • 48,427
  • 12
  • 87
  • 129
  • Thank you for your answer, it is a perfect explanation. `[ ]` should be `( )` no? I made a jsFiddle with the `( )`: https://jsfiddle.net/07osg7ae/1/ – gr3g Feb 21 '15 at 23:52
  • @gr3g, `[]` if you are referencing an array directly; `()` if you are exposing it as a function. If you are using a function, then I suggest that you use `index % 7` within the function, rather than in the View - it's a better separation of concerns. – New Dev Feb 21 '15 at 23:53
  • You are totaly right, I do not even need a function – gr3g Feb 22 '15 at 00:00
  • @gr3g, you don't need it, but then it forces you to add logic of `$index % 7` to the view, which is not very clean – New Dev Feb 22 '15 at 00:01
  • Oh, just read your update. Making operation in the function is better? – gr3g Feb 22 '15 at 00:01
  • @gr3g, function is better to hide away some logic from the View. See another update – New Dev Feb 22 '15 at 00:04
  • In fact I need it to repeat the number of days that are defined in the month. (Can be 28 sometimes). This value is reached in the ng-repeat. – gr3g Feb 22 '15 at 00:24
  • @gr3g, ok, well... then a function is a way to go. – New Dev Feb 22 '15 at 00:26