Home > Software design >  Validation breaks dropdown in Angular 13 in FormGroup
Validation breaks dropdown in Angular 13 in FormGroup

Time:07-04

I have spent last couple of hours to populate dropdown in my form in angular 13, and finally I have managed to make it work, although it wasnt problem in code to populate dropdown it is other controls that break my dropdown:

For example:

@Component({
  selector: 'app-company-add',
  templateUrl: './company-add.component.html',
  styleUrls: ['./company-add.component.css']
})
export class CompanyAddComponent implements OnInit {

 currencies: Currency[] = [];

  form = new FormGroup({
    name: new FormControl('',[Validators.required]),     
    currency: new FormControl('', Validators.required),
    address: new FormGroup({
        street: new FormControl('',[Validators.required]),
        city: new FormControl('',[Validators.required]),
        country: new FormControl('',[Validators.required]),
    })
  });


  constructor( public companyService: CompanyService, public currencyService: CurrencyService,
    private router: Router) {

     }

  ngOnInit() {
    this.currencyService.getAll().subscribe((data: Currency[])=>{
      this.currencies = data;
      console.log(this.currencies);    
    })  
}

  get f(){
    return this.form.controls;
  }
  
  submit(){
    console.log(this.form.value);
    this.companyService.create(this.form.value).subscribe((res:any) => {
      console.log(res);
         console.log('Post created successfully!');
         this.router.navigateByUrl('details');
    })
  }
}

<form [formGroup]="form" (ngSubmit)="submit()">
<div >

    <div >
        <h2>Add new company</h2>
        <label for="name">Name:</label>
        <input formControlName="name" id="name" type="text"  style="width: auto;">
        <div *ngIf="f['name'].touched && f['name'].invalid" >Name is requiered.
            <div *ngIf="f['name'].errors && f['name'].errors['required']">Name is requiered.</div>
        </div>          

        <label for="currency">Currency:</label>
        <select formControlName="currency" >
            <option disabled>Select Currency</option>
            <option>Choose Currency</option>
            <option *ngFor="let currency of currencies">{{currency.name}}</option>
        </select>

    </div>

    <div >
        <div formGroupName="address">
            <h2>Address</h2>
            <label for="street">Street:</label>
            <input formControlName="street" id="street" type="text"  style="width: auto;">
            <div *ngIf="f['street'].touched && f['street'].invalid" >
                Street is
                required.
                <div *ngIf="f['street'].errors && f['street'].errors['required']">Street is
                    required.</div>
            </div>
            <label for="city">City:</label>
            <input formControlName="city" id="city" type="text"  style="width: auto;">
            <div *ngIf="f['city'].touched && f['city'].invalid" >
                City is required.
                <div *ngIf="f['city'].errors && f['city'].errors['required']">City is required.
                </div>
            </div>
            <label for="zipCode">ZipCode:</label>
            <input formControlName="zipCode" id="zipCode" type="text"  style="width: auto;">
            <div *ngIf="f['zipCode'].touched && f['zipCode'].invalid" >
                ZipCode is required.
                <div *ngIf="f['zipCode'].errors && f['zipCode'].errors['required']">ZipCode is
                    required.</div>
            </div>

            <label for="country">Country:</label>
            <input formControlName="country" id="country" type="text"  style="width: auto;">
            <div *ngIf="f['country'].touched && f['country'].invalid" >
                Country is required.
                <div *ngIf="f['country'].errors && f['country'].errors['required']">Country is
                    required.</div>
            </div>

        </div>
    </div>
</div>
<div >
<button  type="submit" [disabled]="!form.valid">Submit</button>

My dropdown is blank when I have validators in my formGroupName= "address"

This breaks the dropdown:

<div *ngIf="f['street'].touched && f['street'].invalid" >
                Street is
                required.
                <div *ngIf="f['street'].errors && f['street'].errors['required']">Street is
                    required.</div>
            </div>

Anyone has suggestion how to fix it so I can have validators on every control?

CodePudding user response:

In your example, f['street'] is an invalid path, because street is not a direct descendant of form. The correct notation is f['address'].controls['street'].

To further improve, I would advise you drop the get f() and just use the built-in getter to access form controls. This will allow you to easily access nested controls, in your case for example form.get('address.street') or form.get('address.city').

  • Related