Search code examples
javascriptangularjsng-options

Ng-Options Expression Repeatedly Called


I am having multiple issues with my <select> element in angular and am trying to understand what is going on. My first step is to understand why the multiple console.log() messages I have put in for debugging repeatedly appear in the console, as in, instead of the message appearing once like I would expect, they appear an infinite number of times, as if part of an infinite loop. Is this how a function called from an ng-options is supposed to behave? If so, I don't understand why, if not, then I would like to fix my loop.

My html: <select ng-options="theorderdate as theorderdate for theorderdate in getOtherOrderDates(Bread.text)" ng-model="randomDateRomantic.randomDateRomantic" ng-change="soRomantic(Bread.text)"></select>

The console.log() messages appear from the getOtherOrderDates() function, which is below (with my comments included):

$scope.getOtherOrderDates = function(loaf) {
  var istheLoafdaily = false;
  var theorderdates = [];
  for (var i = 0; i < $scope.theBreadsList.length; i++) {
    for (var z = 0; z < $scope.theBreadsList[i].breads.length; z++) {
      if ($scope.theBreadsList[i].breads[z].text == loaf && i > 0) //not a daily loaf, goes beyond "Daily Breads" 
      {
        console.log(theorderdates);
        theorderdates = theorderdates.concat($scope.theBreadsList[i].breads[z].orderDates); //concat the matched bread's order dates
        console.log(theorderdates, $scope.theBreadsList[i].breads[z].orderDates);
        theorderdates = _.sortBy(theorderdates, function(m) {
          return m.getTime()
        });
        for (var y = 0; y < theorderdates.length; y++) {
          theorderdates[y] = theorderdates[y].toLocaleDateString();
        }
        theorderdates = _.uniq(theorderdates);
        if (theorderdates.length > 0) {
          console.log("Something is wrong here"); //problem
          $scope.randomDateRomantic.randomDateRomantic = theorderdates[0];
        }
        console.log(theorderdates);
        return theorderdates;
      } else if ($scope.theBreadsList[i].breads[z].text == loaf && i == 0) { //a daily loaf, i == 0
        console.log("The bread matched is daily", loaf); //***
        istheLoafdaily = true;
        console.log(theorderdates); //***
        theorderdates = theorderdates.concat($scope.theBreadsList[i].breads[z].orderDates); // concat the matched bread's order dates
        console.log(theorderdates, $scope.theBreadsList[i].breads[z].orderDates); //***
        break; // escape the for loop, should it be two breaks?????? yes...
      } else if (istheLoafdaily && i > 0 && $scope.theBreadsList[i].breads[z].orderDates.length > 0) { //not sure what scenario this matches, hence wtf
        theorderdates = theorderdates.concat($scope.theBreadsList[i].breads[z].orderDates);
        console.log("wtf");
      }

    }
  }
  //end of outermost for loop
  //not sure what this is doing because this functionality is repeated up there^ (for non-daily breads)
  theorderdates = _.sortBy(theorderdates, function(m) {
    return m.getTime()
  });
  for (var y = 0; y < theorderdates.length; y++) {
    theorderdates[y] = theorderdates[y].toLocaleDateString();
  }
  theorderdates = _.uniq(theorderdates);

  if (theorderdates.length > 0) {
    $scope.randomDateRomantic.randomDateRomantic = theorderdates[0];
    console.log("Something is wrong here (daily)"); //problem
  }
  return theorderdates;
  //not sure what this is doing because this functionality is repeated up there^ (for non-daily breads)
  //if change to Locale date string then not unique, but if don't change then not a date to sort!!!!!!! >:(
},

I am getting almost all console messages an infinite number of times, without doing anything such as firing the ng-change function. I just add a daily bread to my cart for instance, and then the console gets filled with the following messages, that I have starred in my code.

My theBreadsList is not very long, so there is something going on that it is going repeatedly like this. Even if I broke out of the for loop twice as you will see in my code, it wouldn't explain the fact that it logs to the console all the time, because eventually the loop would not be satisfied, and this wouldn't take to long as has been mentioned.

Please advise, thank you. If you need more information, I am happy to provide.


Solution

  • The getOtherOrderDates will be called in each digest cycle so that angular knows whether to update options in select. That's most likely the reason you're seeing this method being called many times.

    If you're worried about performance impact of this loop you can build the options upfront inside your controller store it in $scope like so:

    $scope.options = $scope.getOtherOrderDates($scope.Bread.text);
    

    whenever $scope.Bread.text changes and then use $scope.options inside your template.