Home > Software engineering >  After call setErrors method in FormControl doesn't show inmediately (Angular Material)
After call setErrors method in FormControl doesn't show inmediately (Angular Material)

Time:11-06

I have the following problem when call setErrors in textbox FormControl instance as show it in images bellow.

enter image description here

There should show error message inmediately and no when I remove entire text.

enter image description here

Here is html code.

 <mat-form-field appearance="outline" >
                  <mat-label>Registro Venta</mat-label>
                  <input type="text" 
                  placeholder="Buscar..." 
                  matInput 
                  (input)="setFilter(input.value)"
                  [matAutocomplete]="auto" 
                  [formControl]="registroVentaControl"                
                  (keyup.enter)="addOption()"
                  
                  #input required />
                  <mat-autocomplete #auto="matAutocomplete" [displayWith]="displayFn.bind(this)"
                      (optionSelected)="optionSelected($event.option)"
                      >                    
                      <mat-option *ngFor="let option of registroVentaList" [value]="option">
                          {{option.displayRegistroVentaConsecutivo}}
                      </mat-option>
                  </mat-autocomplete>
                  <mat-error>El registro de venta no esta activo en SAP</mat-error>
              </mat-form-field>

And here is when setErrors is called.

  displayFn(data: RegistroVentaDto): string {

    let registroVentaDto =data as RegistroVentaDto;
    let displayRegistroVentaTemp : string;

    if( registroVentaDto.registroVentaConsecutivo) {
      displayRegistroVentaTemp =  registroVentaDto.displayRegistroVentaConsecutivo;
    }

    if(!displayRegistroVentaTemp)
      return;

    if(!registroVentaDto.registroVentaId || registroVentaDto.registroVentaId <= 0){
      displayRegistroVentaTemp = registroVentaDto.registroVentaConsecutivo;
    }


    this.contractService.getStatusSales(registroVentaDto.registroVentaConsecutivo).subscribe(
      res => {
        if(res)
        {
          this.enableUpdateButton = true;
        }
        else{
          this.notificationService.openError(`Registro de venta '${displayRegistroVentaTemp}' no activo en SAP.`);
          this.registroVentaControl.setErrors({'invalid': true});//Here
          this.registroVentaControl.updateValueAndValidity({ onlySelf: false, emitEvent: true });//Here
          this.enableUpdateButton = false;          
        }
      });

    return displayRegistroVentaTemp;
  }

I tried to use

this.registroVentaControl.updateValueAndValidity({ onlySelf: false, emitEvent: true });

But, it didn't work

CodePudding user response:

You can try using changeDetectorRef

  • Remove updateValueAndValidity method calls
  • Mark the control as touched when it has value and untouched when the input is empty
  • Set error value to true or false respectively
  • Call detectChanges to force Angular to render the error state
constructor(private changeDetectorRef: ChangeDetectorRef) { }

ngOnInit() {
    this.registroVentaControl.valueChanges.subscribe(val => {
      if(val.length === 0){
        this.registroVentaControl.markAsUntouched()
        this.registroVentaControl.setErrors({'invalid': false})
        this.changeDetectorRef.detectChanges(); 
      }
    })
}

this.contractService
  .getStatusSales(registroVentaDto.registroVentaConsecutivo)
  .subscribe((res) => {
    if (res) {
      this.enableUpdateButton = true;
    } else {
      this.notificationService.openError(
        `Registro de venta '${displayRegistroVentaTemp}' no activo en SAP.`
      );
      this.registroVentaControl.markAsTouched();
      this.registroVentaControl.setErrors({ invalid: true });
      this.changeDetectorRef.detectChanges();
      this.enableUpdateButton = false;
    }
  });
  • Related