Validator não deixa passar - resolvido

Tenho este form

<form [formGroup]="terceiroFormGroup">
   <ng-template matStepLabel>Dados Adicionais</ng-template>
   <div fxLayout="row" fxLayoutAlign="space-evenly stretch">
   <div fxFlex.gt-sm="40" fxFlex.gt-xs="40" fxFlex="40">
   <mat-form-field>
   <input matInput placeholder="CEP" id="cep" formControlName="cep" 
   name="cep" maxlength="11" [textMask]="{mask: cep}">
   <mat-icon matSuffix (click)="buscarCep()">search</mat-icon>
   </mat-form-field>
   </div>
   <div fxFlex.gt-sm="40" fxFlex.gt-xs="40" fxFlex="40">
   <mat-form-field>
   <input matInput placeholder="Tipo de logradouro" id="tipoLogradouro"
   formControlName="tipoLogradouro" name="tipoLogradouro" 
    value="{{endereco?.tipoLogradouro}}">
    </mat-form-field>
    </div>
    </div>
    <div fxLayout="row" fxLayoutAlign="space-evenly stretch">
    <div fxFlex.gt-sm="40" fxFlex.gt-xs="40" fxFlex="40">
    <mat-form-field>
    <input matInput placeholder="Logradouro" id="logradouro" 
    formControlName="logradouro" name="logradouro" value="{{endereco?.logradouro}}">
    </mat-form-field>
    </div>
    <div fxFlex.gt-sm="40" fxFlex.gt-xs="40" fxFlex="40">
    <mat-form-field>
    <input matInput placeholder="Número" id="numero" 
    formControlName="numero" name="numero">
    </mat-form-field>
    </div>
    </div>
    <div fxLayout="row" fxLayoutAlign="space-evenly stretch">
    <div fxFlex.gt-sm="40" fxFlex.gt-xs="40" fxFlex="40">
    <mat-form-field>
    <input matInput placeholder="Complemento" id="complemento"
    formControlName="complemento" name="complemento" value="{{endereco?.complemento}}">
    </mat-form-field>
    </div>
    <div fxFlex.gt-sm="40" fxFlex.gt-xs="40" fxFlex="40">
    <mat-form-field>
    <input matInput placeholder="Bairro" id="bairro" 
    formControlName="bairro" name="bairro" value="{{endereco?.bairro}}">
    </mat-form-field>
    </div>
    </div>
    <div fxLayout="row" fxLayoutAlign="space-evenly stretch">
    <div fxFlex.gt-sm="40" fxFlex.gt-xs="40" fxFlex="40">
    <mat-form-field>
    <input matInput placeholder="Cidade" id="cidade" 
    formControlName="cidade" name="cidade" value="{{endereco?.cidade}}">
     </mat-form-field>
     </div>
     <div fxFlex.gt-sm="40" fxFlex.gt-xs="40" fxFlex="40">
     <mat-form-field>
      <mat-label>Estado</mat-label>
      <mat-select id="estado" formControlName="estado" 
      name="estado" [(value)]="estadoSelecionado">
      <mat-option></mat-option>
      <mat-option *ngFor="let estado of estados" [value]="estado">
      {{estado.nome}}
      </mat-option>
      </mat-select>
      </mat-form-field>
      </div>
      </div>
      </form>

A construção do form

terceiroFormGroup = this.fb.group({
    cep: ['', [
      Validators.required,
      Validators.minLength(10),
      Validators.maxLength(10),
    ]],
    tipoLogradouro: ['', [
      Validators.required,
      Validators.maxLength(100),
    ]],
    logradouro: ['', [
      Validators.required,
      Validators.maxLength(100),
    ]],
    numero: ['', [
      Validators.required,
      Validators.maxLength(8),
    ]],
   complemento: ['', Validators.maxLength(100)],
    bairro: ['', [
      Validators.required,
      Validators.maxLength(100),
    ]],
    cidade: ['', [
      Validators.required,
      Validators.maxLength(100),
    ]],
    estado: ['', [
      Validators.required,
    ]],
  });

No componente CEP, tem um botão conforme imagem
Ao clicar ele vai no servidor e busca o endereço e retorna corretamente.

buscarCep(): void {
    this.endereco = {};
    this.estadoSelecionado = {};
    if(this.terceiroFormGroup.value.cep !== undefined && this.terceiroFormGroup.value.cep !== '' 
      && this.terceiroFormGroup.value.cep !== null) {
      this.correiosService.enderecoPeloCep(this.terceiroFormGroup.value.cep).subscribe(
        endereco => {
          this.endereco = endereco;
          this.estados.forEach((objeto: EstadoModel) => {
            if(objeto.sigla === endereco?.estado) {
              this.estadoSelecionado = objeto;
            }
          })
          this.terceiroFormGroup.value.bairro = endereco?.bairro;
          this.terceiroFormGroup.value.cidade = endereco?.cidade;
          this.terceiroFormGroup.value.complemento = endereco?.complemento;
          this.terceiroFormGroup.value.estado = endereco?.estado;
          this.terceiroFormGroup.value.logradouro = endereco?.logradouro;
          this.terceiroFormGroup.value.tipoLogradouro = endereco?.tipoLogradouro;
        }
      );
    }
  }

O problema é quando clico e para salvar e ele não o validator dos campos mostra que eles não foram preenchidos, Conforme imagem

Outro erro estranho

O que pode ser ?

Pelo que li na doc, parece que vc tem que atualizar partes do form usando as funções setValue ou patchValue.

Imagino que seria algo assim:

this.estados.forEach((objeto: EstadoModel) => {
	if(objeto.sigla === endereco?.estado) {
		this.terceiroFormGroup.estadoSelecionado.setValue(objeto);
	}
});

this.terceiroFormGroup.patchValue({
	bairro: endereco?.bairro,
	cidade: endereco?.cidade,
	complemento: endereco?.complemento,
	estado: endereco?.estado,
	logradouro: endereco?.logradouro,
	tipoLogradouro: endereco?.tipoLogradouro
});

Cuidado ao usar o patchValue, parece que, em caso de erro, ele não aivsa nada, porém, o setValue já avisa no caso de acontecer algum erro.

FONTE: https://angular.io/guide/reactive-forms#updating-parts-of-the-data-model

1 curtida

Este não preenche o estado

this.estados.forEach((objeto: EstadoModel) => {
            if(objeto.sigla === endereco?.estado) {
              this.terceiroFormGroup.value.estado.setValue(objeto);
            }
          })

Continua sem funcionar

this.correiosService.enderecoPeloCep(this.terceiroFormGroup.value.cep).subscribe(
        endereco => {
          this.endereco = endereco;
          this.estados.forEach((objeto: EstadoModel) => {
            if(objeto.sigla === endereco?.estado) {
              this.terceiroFormGroup.value.estado.setValue(objeto);
            }
          })
         this.terceiroFormGroup.value.bairro.setValue(endereco?.bairro);
         this.terceiroFormGroup.value.cidade.setValue(endereco?.cidade);
         this.terceiroFormGroup.value.complemento.setValue(endereco?.complemento);
         this.terceiroFormGroup.value.estado.setValue(endereco?.estado);
         this.terceiroFormGroup.value.logradouro.setValue(endereco?.logradouro);
         this.terceiroFormGroup.value.tipoLogradouro.setValue(endereco?.tipoLogradouro);
        },
        (error: any) => {
          const errorMessage = new MensagemModel();
          const errorMessages: Array<MensagemModel> = [];
          errorMessage.texto = error.error.title;
          errorMessages.push(errorMessage);
          super.mensagemTela('ERROR', errorMessages);
        }
      );

Preenche os campos, mas o validator, não deixa passar.

O que pode ser ?

Além do mais, mostra este erro

core.js?7d7a:5873 ERROR TypeError: this.terceiroFormGroup.value.estado.setValue is not a function
    at eval (registro.component.ts?bf26:287)
    at Array.forEach (<anonymous>)
    at SafeSubscriber.eval [as _next] (registro.component.ts?bf26:285)
    at SafeSubscriber.__tryOrUnsub (Subscriber.js?ee8f:183)
    at SafeSubscriber.next (Subscriber.js?ee8f:122)
    at Subscriber._next (Subscriber.js?ee8f:72)
    at Subscriber.next (Subscriber.js?ee8f:49)
    at MapSubscriber._next (map.js?949c:35)
    at MapSubscriber.next (Subscriber.js?ee8f:49)
    at FilterSubscriber._next (filter.js?a4b6:33)

Tenta assim:

this.terceiroFormGroup.controls.bairro.setValue(endereco?.bairro);

this.terceiroFormGroup.controls.bairro.setValue(endereco?.bairro);

não funcionou

Funcionou. Fiz outro formulário e funcionou.

obrigado