1

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

Paintbox
  • 359
  • 5
  • 12
  • The most likely cause for this error is this ngIf: `*ngIf="validateControl('gender') && hasError('gender', 'required')"` But it's hard to tell without more of the template code. If you can identify the ngIf that's causing it, debugging would be easier. The official Angular video on this error is the best source for debugging it: https://www.youtube.com/watch?v=O47uUnJjbJc – Meqwz Sep 27 '21 at 12:58
  • Thanks for your help. I already saw this video but it's not enough clear for mer. – Paintbox Sep 27 '21 at 13:04
  • If could comment out the ngIfs in your template code until you find the one that's causing the error and then post that, it would help solve your issue. – Meqwz Sep 27 '21 at 13:49
  • It's the ngIf liked to the call of the child component ` Sélectionnez un genre` – Paintbox Sep 27 '21 at 13:56
  • Someone knows if it's possible to cancel validation when form is loaded? The idee is to validate only when the form is submited. – Paintbox Sep 27 '21 at 15:47
  • Read this https://loiane.com/2017/08/angular-reactive-forms-trigger-validation-on-submit/ Stackblitz https://stackblitz.com/edit/github-ouphmf?file=src/app/submit-flag-form/submit-flag-form.component.html – Meqwz Sep 27 '21 at 16:42
  • Thanks for the link but it doesn't resolve my problem. The error message ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'true'. Current value: 'false' is always present. – Paintbox Sep 28 '21 at 07:41

1 Answers1

9

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.

Paintbox
  • 359
  • 5
  • 12