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>

2
  • 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. Commented Feb 21, 2015 at 23:16
  • I had to repost a easier way to explain the problem. Previous question will be deleted Commented Feb 21, 2015 at 23:18

1 Answer 1

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>
Sign up to request clarification or add additional context in comments.

8 Comments

Thank you for your answer, it is a perfect explanation. [ ] should be ( ) no? I made a jsFiddle with the ( ): jsfiddle.net/07osg7ae/1
@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.
You are totaly right, I do not even need a function
@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
Oh, just read your update. Making operation in the function is better?
|

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.