javascript - Angular 7, Ngrx, ExpressionChangedAfterItHasBeenCheckedError - Stack Overflow

was looking for a longer while but couldn't find anything.I have a template like so:<learning-n

was looking for a longer while but couldn't find anything.

I have a template like so:

<learning-navigation *ngIf="(_navigationSelectedSafe$ | async) == _navigationLayout.location" [(selectMode)]="_navigationModeSelected"></learning-navigation>

Where:

private _navigationSelected$: Observable<string>;
private _navigationSelectedSafe$ = new EventEmitter<any>(true);

...

this._navigationSelected$.subscribe(res => {
  ...
  this._navigationSelectedSafe$.emit(res)
});

with the input of learning-navigation being a setter:

  @Input()
  set selectMode(mode: number) {
    this.mode = mode;
  }

This causes the error:

ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'selectMode: null'. Current value: 'selectMode: 1'. 

I already tried changing the EventEmitter to a BehaviourSubject, forcing detectChanges() after ngInit and ngAfterChecked (Although this wouldn't be optimal even if it worked) and also wrapping it around in a container trying to pass the mode directly async into the ponent while just controlling the display with an extra if.

The current solution works and it doesn't seem there are any side effects but it throws the error regardless every time mode changes. Thanks

was looking for a longer while but couldn't find anything.

I have a template like so:

<learning-navigation *ngIf="(_navigationSelectedSafe$ | async) == _navigationLayout.location" [(selectMode)]="_navigationModeSelected"></learning-navigation>

Where:

private _navigationSelected$: Observable<string>;
private _navigationSelectedSafe$ = new EventEmitter<any>(true);

...

this._navigationSelected$.subscribe(res => {
  ...
  this._navigationSelectedSafe$.emit(res)
});

with the input of learning-navigation being a setter:

  @Input()
  set selectMode(mode: number) {
    this.mode = mode;
  }

This causes the error:

ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'selectMode: null'. Current value: 'selectMode: 1'. 

I already tried changing the EventEmitter to a BehaviourSubject, forcing detectChanges() after ngInit and ngAfterChecked (Although this wouldn't be optimal even if it worked) and also wrapping it around in a container trying to pass the mode directly async into the ponent while just controlling the display with an extra if.

The current solution works and it doesn't seem there are any side effects but it throws the error regardless every time mode changes. Thanks

Share Improve this question asked Jun 19, 2019 at 8:41 qubitsqubits 1,3073 gold badges21 silver badges53 bronze badges 2
  • 1 I don't know what the rest of the logic of your ponent is but if it's just a presentational ponent you could set the changeDetection: ChangeDetectionStrategy.OnPush. This way the change detector will be called only when the input is updated – Antonis Commented Jun 19, 2019 at 9:20
  • Changing the push detection worked. Can you please formulate it into a nice answer? Thanks. – qubits Commented Jun 19, 2019 at 9:36
Add a ment  | 

2 Answers 2

Reset to default 10

Your problem indicates that there was a change of value outside Angular's change detection. This can happen for multiple reasons. In your case it's the asynchronous nature of your input I guess.

If your ponent is a presentational ponent, you can set the change detection strategy to onPush.

This way your change detector will run only when there's a new value on your input

example:

@Component({
  selector: 'app-your-p',
  templateUrl: './app-your-p.ponent.html',
  styleUrls: ['./app-your-p.ponent.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush
})
<ng-container *ngIf="_navigationSelectedSafe$ | async as selectedSafe">
  <learning-navigation *ngIf="selectedSafe == _navigationLayout.location" 
    [(selectMode)]="_navigationModeSelected"></learning-navigation>
</ng-container>

This will prevent the learning-navigation element frop being displayed when the value of your observable is null, thus erasing your error.

EDIT

Use a timeout in your setter to resolve any further issue :

@Input()
set selectMode(mode: number) {
  setTimeout(() => this.mode = mode);
}

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745674691a4639615.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信