Paintbox
Paintbox

Reputation: 407

Error ExpressionChangedAfterItHasBeenCheckedError with child component in Angular

I have created a child component for genders. I use it in my main form. Values for gender component are loaded in this child component and I have an input property to set selected value.

export class GenderComponent implements OnInit {
  public errorMessage: string = '';
  @Input() public genders: Gender[];
  @Input() public selectedValue?: string ="";
  @Input() public myForm: FormGroup;

  constructor(private repository: RepositoryService, private controlContainer: ControlContainer,    private errorHandler: ErrorHandlerService, private cd: ChangeDetectorRef) { }

  ngOnInit(): void {
    this.myForm = <FormGroup>this.controlContainer.control;
    this.getGenders();
}
  
  getGenders = () => {
   let apiGender: string = environment.apiAddress + 'Gender'; 
   this.repository.getData(apiGender)
   .subscribe(response => {
   this.genders = response as Gender[];
  },
  (error) => {
    this.errorHandler.handleError(error);
    this.errorMessage = this.errorHandler.errorMessage;
  })
}

  ngAfterViewInit(){
     this.cd.detectChanges();
  }
}

I call the component like this in the main form (parent) :

<app-gender name="gender" id="gender" [formGroup]="myForm" [selectedValue]="user?.gender?.description">
   <em *ngIf="validateControl('gender') && hasError('gender', 'required')">Sélectionnez un genre</em>
</app-gender>

and as you can see I ask validation for this child component. This main form is destinated to update user profile. Therefor I load user profile from Web Api like this :

public loadUserDetails = () => {
  let id: string = this.activeRoute.snapshot.params['id'];
  let apiUser: string = environment.apiAddress + 'UserAccount' + '/' + id;

  this.repository.getData(apiUser).pipe()
    .subscribe(response => {
      this.user = response as UserAccount;
      this.myForm.patchValue({
      firstname: (<UserAccount>response).firstName,
      lastname: (<UserAccount>response).lastName,
      mail: (<UserAccount>response).mail,
      genderId: (<UserAccount>response).genderId,
      password: (<UserAccount>response).password,
      username: (<UserAccount>response).userName,
      login: (<UserAccount>response).login,
      useraccountTypeId: (<UserAccount>response).useraccountTypeId,
     })
   },
   (error) => {
     this.errorHandler.handleError(error);
     this.errorMessage = this.errorHandler.errorMessage;
   })
 }

I have the following error message : ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'true'.

I understand that the problem is due to the fact that I set genderId after user profile values are loaded.

I have found several posts about same subject but I can't adapt them to mine.

Is there anybody who can help me?

Thanks

Upvotes: 2

Views: 7783

Answers (1)

Paintbox
Paintbox

Reputation: 407

It's seems that I solved my problem thanks to this post.

I added this into my parent form and I don't have the error message anymore.

ngAfterViewChecked(): void {
    this.changeDetectorRef.detectChanges();
}

The class must implement AfterViewChecked and the constructor needs to have private readonly changeDetectorRef: ChangeDetectorRef

Hoping that can help others. Thanks for your help.

Upvotes: 11

Related Questions