ERROR Error: Cannot find control with name: reactiveForms Angular

53 Views Asked by At

I'm trying to insert data into two tables in my database, 'client' and 'address.' I want to do this through a form that includes fields for both the client and the address. The idea is that the address fields should be displayed when I click an 'insert' button, revealing the address input fields while hiding some other fields such as password and passport data. These fields should be hidden again when I click 'OK.' The problem is that when I click 'OK,' the data is lost as soon as I open the insert form again, and it returns the following error in my console:

ERROR Error: Cannot find control with name: 'pais'
    at _throwError (forms.mjs:3150:11)
    at setUpControl (forms.mjs:2933:13)
    at FormGroupDirective.addControl (forms.mjs:4782:9)
    at FormControlName._setUpControl (forms.mjs:5370:43)
    at FormControlName.ngOnChanges (forms.mjs:5315:18)
    at FormControlName.rememberChangeHistoryAndInvokeOnChangesHook (core.mjs:3032:14)
    at callHookInternal (core.mjs:4024:14)
    at callHook (core.mjs:4055:9)
    at callHooks (core.mjs:4006:17)
    at executeInitAndCheckHooks (core.mjs:3956:9)

and the other error:

core.mjs:10614 ERROR TypeError: control.registerOnChange is not a function
    at setUpModelChangePipeline (forms.mjs:3116:13)
    at setUpControl (forms.mjs:2946:5)
    at FormGroupDirective.addControl (forms.mjs:4782:9)
    at FormControlName._setUpControl (forms.mjs:5370:43)
    at FormControlName.ngOnChanges (forms.mjs:5315:18)
    at FormControlName.rememberChangeHistoryAndInvokeOnChangesHook (core.mjs:3032:14)
    at callHookInternal (core.mjs:4024:14)
    at callHook (core.mjs:4055:9)
    at callHooks (core.mjs:4006:17)
    at executeInitAndCheckHooks (core.mjs:3956:9)

my form code:

  <form class="form" [formGroup]="formClient" (ngSubmit)="onSubmit()">
    Nome completo
    <input
      type="text"
      class="form-control"
      placeholder="Nome"
      formControlName="nome"
    />
  

  <div class="form-group">
    <label for="email">E-mail</label>
    <input
      type="text"
      class="form-control"
      placeholder="E-mail"
      formControlName="email"
    />
  </div>
</div>

<div class="form-row">
  <div class="form-group">
    <span *ngIf="!showAddressForm && !showPassportForm">
      Endereço
      <button
        *ngIf="!showAddressForm && !showPassportForm"
        type="button"
        class="btn btn-primary"
        (click)="toggleAddressForm()"
      >
        Inserir
      </button>
    </span>

    <span *ngIf="!showAddressForm && !showPassportForm">
      Dados do Passaporte
      <button
        type="button"
        class="btn btn-primary"
        (click)="togglePassportForm()"
      >
        Inserir
      </button>
    </span>
  </div>

  <div class="form-group" *ngIf="!showAddressForm && !showPassportForm">
    <label for="senha">Senha</label>
    <input
      type="password"
      class="form-control"
      placeholder="Senha"
      formControlName="senha"
    />
  </div>
</div>

<div *ngIf="showAddressForm">
  <div class="form-group">
    <label for="pais">País</label>
    <input
      type="text"
      class="form-control"
      placeholder="País"
      formControlName="pais"
    />
  </div>
  <div class="form-group">
    <label for="endereco">Endereço</label>
    <input
      type="text"
      class="form-control"
      placeholder="Endereço"
      formControlName="endereco"
    />
  </div>

  <button class="btn btn-success" (click)="saveAddress()">OK</button>
</div>

<div class="form-row" *ngIf="showPassportForm">
  <button class="btn btn-success" (click)="savePassport()">OK</button>
</div>

<button
  *ngIf="!showAddressForm && !showPassportForm"
  class="buttonSubmitRegister"
  type="submit"
>
  Cadastrar
</button>

my .ts code:

import { Component, OnInit } from '@angular/core';
import { Client } from 'src/app/models/Client/client';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { ClientService } from '../../services/api/apiservice.service';
import { Address } from 'src/app/models/Address/address';

@Component({
  selector: 'app-signup',
  templateUrl: './signup.component.html',
  styleUrls: ['./signup.component.scss'],
})
export class SignupComponent implements OnInit {
  clientArray: any[] = [];
  isResultLoaded = false;
  showAddressForm: boolean = false;
  showPassportForm: boolean = false;
  formClient!: FormGroup;
  formAddress!: FormGroup;
  addressData: any = {};

  toggleAddressForm() {
    this.showAddressForm = true;
    this.showPassportForm = false;
  }

  togglePassportForm() {
    this.showAddressForm = false;
    this.showPassportForm = true;
  }

  savePassport() {
    this.showPassportForm = false;
  }

  constructor(private fb: FormBuilder, private clientService: ClientService) {
    this.getAllStudent();
  }

  ngOnInit(): void {
    this.createAddress(new Address('', '', '', ''));
    this.createForm(
      new Client('', '', '', '', '', '', '', this.formAddress.value)
    );
  }
  
  createAddress(address: Address) {
    this.formAddress = this.fb.group({
      pais: [address.country, Validators.required],
      endereco: [address.address, Validators.required],
      cidade: [address.city, Validators.required],
      cep: [address.zipcode, Validators.required],
    });
  
    console.log(this.formAddress.value);
  }
  
  createForm(client: Client) {  
    this.formClient = this.fb.group({
      nome: [client.name, Validators.required],
      email: [client.email, Validators.email],
      phone: [client.phone, Validators.required],
      nascimento: [client.birthdate, Validators.required],
      nacionalidade: [client.nationality, Validators.required],
      genero: [client.gender, Validators.required],
      senha: [client.password, Validators.required],
      endereco: this.formAddress,
    });
  }
  

  saveAddress() {
    this.addressData = this.formAddress.value;
    this.showAddressForm = false;
  }

  register() {
    console.log('Dados enviados para o servidor:', this.formClient.value);

    if (this.formClient.valid) {
      const clientData = {
        ...this.formClient.value,
        address: this.formAddress.value,
      };

      this.clientService.addClient(clientData).subscribe({
        next: (resultData: any) => {
          console.log(resultData);
          alert('Sucesso ao registrar');
          this.getAllStudent();
        },
        error: (error) => {
          console.error('Erro ao registrar:', error);
        },
      });
    }
  }

  onSubmit() {
    console.log(this.formClient.value);
    this.register();
  }
}

Link to my project on github:

My idea is in the images.Image 1: with the insert button for address (endereço) image 2: with the fields to insert data into the address

I just want the fields (password, passport data, insert button) to be hidden when I open my address or passport insertion form, but the data I entered in the fields should still exist. And when I click 'insert' again, the data should be displayed in the fields until I click 'submit,' and they are sent to my database.

1

There are 1 best solutions below

0
Camis Aguiar On

I managed to solve it. The issue was that I wasn't specifying the formGroup within my div with the address data, so the formControl 'country' wasn't being recognized. I'm not sure about the second error, but it was resolved anyway. The code is updated in my repository, and here are the changes I made:

 <div *ngIf="showAddressForm" class="form-row">
  <h2>Endereço</h2>
  <div [formGroup]="formAddress" formclass="form-row">
    <div class="form-group">
      <label for="pais">País</label>
      <input
        type="text"
        class="form-control"
        placeholder="País"
        formControlName="pais"
      />
    </div>

And to save the data after clicking 'OK' to send it to the database, I created a variable called savedAddressData and initialized it as an empty object ({}) where I store my formGroup, ensuring it won't be lost when closing the fields.

my signup.component.ts:

savedAddressData: any = {};
savedPassportData: any = {};

  constructor(private fb: FormBuilder, private clientService: ClientService) {
    this.getAllStudent();
  }

  ngOnInit(): void {
    this.createAddress(new Address('', '', '', ''));
    this.createPassport(new Passport('', '', '', '')); 
    this.createForm(
      new Client(
        '',
        '',
        '',
        '',
        '',
        '',
        '',
        this.formAddress.value,
        this.formPassport.value
      )
    );
  }

  createForm(client: Client) {
    this.formClient = this.fb.group({
      nome: [client.name, Validators.required],
      email: [client.email, Validators.email],
      phone: [client.phone, Validators.required],
      nascimento: [client.birthdate, Validators.required],
      nacionalidade: [client.nationality, Validators.required],
      genero: [client.gender, Validators.required],
      senha: [client.password, Validators.required],
      endereco: this.formAddress,
      passaporte: this.formPassport,
    });
  }

  createAddress(address: Address) {
    this.formAddress = this.fb.group({
      pais: address.country,
      endereco: address.address,
      cidade: address.city,
      cep: address.zipcode,
    });
    console.log(this.formAddress.value);
  }
  createPassport(passport: Passport) {
    this.formPassport = this.fb.group({
      nomePassaporte: passport.namePassport,
      numero: passport.number,
      paisEmissor: passport.issuingCountry,
      dataExpiracao: passport.expirationDate,
    });
  }

  saveAddress() {
    this.savedAddressData = this.formAddress.value;
    this.showAddressForm = false;
    console.log(this.savedAddressData);
  }