-2

I am attempting to populate several rows in a table I created. The table successfully populates, however I get an error:

"ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: '1'. Current value: 'ah'."

This isn't really a problem because the error doesn't crash my program or anything, however whenever I change any of the units in my table, it changes the values of ALL the units to be whatever the "Current value" is in the error above. (in this case, I made it 'ah,' see code below)

This is how I'm populating the table:

<div class="row-container">
  <div *ngFor="let week of getWeeks()" class="row">
    <input class="week" maxlength="2" (input)="type($event.target.value, week)" value="{{getCapacity(week)}}">
  </div>
</div>


And this is how I'm updating the value:

getCapacity(week: Date): string {
    if (<conditions are met>) { 
        const capacity = EntryComponent.capacity[EntryComponent.index];
        EntryComponent.index++;
        return capacity.value;
    }
    return 'ah';
}

I'm not using a dynamic component as a tag, but rather dynamically changing the value of my input tag.

Visualizes
  • 39
  • 5
  • I think you can guess: you should've put a binding in value and change it. – Vega Aug 11 '17 at 21:08
  • Possible duplicate of [Angular dynamic component loading - ExpressionChangedAfterItHasBeenCheckedError](https://stackoverflow.com/questions/43917940/angular-dynamic-component-loading-expressionchangedafterithasbeencheckederror) – Erik Philips Aug 11 '17 at 21:11
  • 1
    In development mode, Angular runs each change loop twice, and the error is occurring because a change is happening in between these (which it shouldn't). It's probably because your first change loop is changing whatever your "" condition is. – LarsMonty Aug 11 '17 at 21:23
  • @LarsMonty Thank you! Put this as the answer and I'll mark it as correct. All I had to do to fix it was reset my index to 0 at the end of the loop, so the conditions could be met again. – Visualizes Aug 11 '17 at 22:43

1 Answers1

1

When in development mode, Angular runs each change detection loop twice - once as it would normally, and a second time in order to make sure nothing changed during the initial loop. If something has changed, the ExpressionChangedAfterItHasBeenCheckedError will be thrown. This does not mean your application will not work, but it is more that Angular is warning you of this behavior.

In your case, the error is in this code:

if (<conditions are met>) {  <--- Creating behavior that causes error
    const capacity = EntryComponent.capacity[EntryComponent.index];
    EntryComponent.index++;
    return capacity.value;
}
return 'ah';

If something occurring inside of the change loop changes that condition, the first loop with return capacity.value, the condition will change, and the second loop will not meet the condition, and return ah. This is causing the error, and it is a proper warning: I would not recommend the target of a binding being dependent on a conditional that is altered during a change loop. I would recommend re-configuring this conditional to be depending on some property of your component instead.

LarsMonty
  • 727
  • 8
  • 20