Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Testing component throws Expression has changed after it was checked, when I try to change value

I am using test host component to control values passed into the component I am trying to test:

@Component({
  selector: `host-component`,
  template: `<edit-text [definition]="definition" [formGroup]="formGroup"></edit-text>`
})
class TestHostComponent {
  formGroup = new FormGroup({
    text: new FormControl('')
  })

  definition: any = {
    name: 'text',
    title: 'Text Field',
    required: false
  }

  @ViewChild(EditTextComponent) component: EditTextComponent
}

Now I would like to test a toggle of required:

  it('should indicate required', () => {
    hostComponent.definition.required = true
    fixture.detectChanges()
    ...
  })

However when I do this I get:

Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value for 'ng-valid': 'true'. Current value: 'false'.

The component I am testing is fairly simple:

@Component({
  selector: 'edit-text',
  templateUrl: './edit-text.component.html',
  styleUrls: ['./edit-text.component.scss']
})
export class EditTextComponent {
  @Input() formGroup: FormGroup
  @Input() definition: any
}

Template:

<div [formGroup]="formGroup">
  <mat-form-field appearance="fill">
    <mat-label>Text</mat-label>
    <input matInput formControlName="{{definition.name}}" [required]="definition.required">
    <mat-error *ngIf="formGroup.get(definition.name).hasError('required')">You must enter a value</mat-error>
  </mat-form-field>
</div>

Can I update the values in the parent (TestHostComponent) to have the component I am trying to test pick up the changes?

like image 468
lostintranslation Avatar asked Jan 21 '26 11:01

lostintranslation


1 Answers

Looks like this might be my problem:

https://github.com/angular/angular/issues/23657

I can update my TestHostComponent:

@Component({
  selector: `host-component`,
  template: `<edit-text [definition]="definition" [formGroup]="formGroup"></edit-text>`,
  changeDetection: ChangeDetectionStrategy.OnPush
})

Seems to do the trick, and I don't update required dynamically in the parent component anywhere other than testing. Still stinks that this is still a known issue with Angular and reactive forms.

like image 107
lostintranslation Avatar answered Jan 24 '26 18:01

lostintranslation



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!