Kasey Kaufmann
Kasey Kaufmann

Reputation: 109

I have a no-loop-func issue that I don't know how or if I should bother solving

Currently, this isn't breaking anything in my code but i keep seeing this is an error that usually causes serious issues but I don't know what's going on really or how to make the error go away. If anyone has any advice, that'd be great.

error: Function declared in a loop contains unsafe references to variable(s) 'i' no-loop-func

Relevant Code Segment:

      let i = 0;
      let interval = moment()
        .day(days[0] + frequency * i)
        .toDate();
      while (moment(endDate).isAfter(interval)) {
        days.map((day) =>
          selectedDays.push(
            moment()
              .day(day + frequency * i)
              .toDate()
          )
        );

        interval = moment()
          .day(days[0] + frequency * ++i)
          .toDate();
      }

Upvotes: 1

Views: 1067

Answers (2)

3limin4t0r
3limin4t0r

Reputation: 21130

Going by the warning:

Function declared in a loop contains unsafe references to variable(s) 'i'

Since your while-loop has only one function declaration (per iteration) we can assume that the following code is the problem:

(day) =>
  selectedDays.push(
    moment()
      .day(day + frequency * i)
      .toDate()
  )

The reference to i within the arrow function triggers the warning, because the JavaScript linter does not know when/where the declared functions are called.

When looking at the no-loop-func rule examples:

for (let i=10; i; i--) {
    var a = function() { return i; }; // OK, all references are referring to block scoped variables in the loop.
    a();
}

You can see that you can resolve this warning by using block scoped variables. When applied to your current code, it might look like this:

while (moment(endDate).isAfter(interval)) {
  // store the value used by the function in a block-scoped constant
  const period = frequency * i;
  days.map((day) =>
    selectedDays.push(
      moment()
        .day(day + period)
        .toDate()
    )
  );
  // ...
}

You should also avoid the use of map() if you are not going to use the return value. For just iteration use forEach() or a for...of loop.

Another option would be to not declare a function at all, this can be done by using for...of.

while (moment(endDate).isAfter(interval)) {
  for (const day of days) {
    selectedDays.push(
      moment()
        .day(day + frequency * i)
        .toDate()
    );
  }
  // ...
}

The above removes the function declaration completely.

Upvotes: 2

CaseyC
CaseyC

Reputation: 1482

This is happening because you are declaring interval outside of your while loop and then modifying it inside the while loop. This can lead to unexpected behavior. You can declare interval inside your while loop at the top and it will probably resolve the error/warning you are seeing.

Upvotes: 1

Related Questions