Created Address Custom Form Controller and using in inside CustomerForm, while submitting the form without filling anything, getting mat error of required field for Customer Code and Customer Name, not getting any mat error of required field in Address1, Country, City, and Zipcode.
I had tried to add a custom validator which is showing a combined error of address. But it is not solving my problem as it is always showing error addresses until all required fields of an address are filled.
customer.component.html
<form (ngSubmit)=" custForm.valid && saveOrUpdateCustomer()" [formGroup]="custForm">
<!-- Customer Code -->
<mat-form-field>
<input matInput placeholder="Customer Code" formControlName="custCode" required >
<mat-error *ngIf="custForm.get('custCode').hasError('required')">
*Required field
</mat-error>
</mat-form-field>
<!-- Customer Name -->
<mat-form-field>
<input matInput placeholder="Customer Name" formControlName="custName" required>
<mat-error *ngIf="custForm.get('custName').hasError('required')">
*Required field
</mat-error>
</mat-form-field>
<h6>Address Details</h6>
<!--Address Detail-->
<app-address formControlName="address" #address></app-address>
<div *ngIf="custForm.controls['address'].hasError('isNotValid')">
</div>
<div>
<button type="submit" >Submit</button>
</div>
</form>
address.component.hml
<form [formGroup]="addressForm">
<!-- Address 1 -->
<mat-form-field>
<input matInput placeholder="Address 1" formControlName="address1" required>
<mat-error *ngIf="addressForm.get('address1').hasError('required')">
*Required field
</mat-error>
</mat-form-field>
`
<!-- Address 2 -->
<mat-form-field>
<input matInput placeholder="Address 2" formControlName="address2">
</mat-form-field>
<!-- Address 3 -->
<mat-form-field>
<input matInput placeholder="Address 3" formControlName="address3">
</mat-form-field>
<!-- Country -->
<mat-form-field>
<input matInput placeholder="Country" formControlName="country" required>
<mat-error *ngIf="addressForm.get('country').hasError('required')">
*Required field
</mat-error>
</mat-form-field>
<!-- State -->
<mat-form-field>
<input matInput placeholder="State" formControlName="state">
</mat-form-field>
<!-- City -->
<mat-form-field>
<input matInput placeholder="City" formControlName="city" required>
<mat-error *ngIf="addressForm.get('country').hasError('required')">
*Required field
</mat-error>
</mat-form-field>
<!-- Zip Code -->
<mat-form-field>
<input matInput placeholder="Zip Code">
<mat-error *ngIf="addressForm.get('country').hasError('required')">
*Required field
</mat-error>
</mat-form-field>
</form>
address.component.ts
import { Component, OnInit, forwardRef} from '@angular/core';
import { FormGroup, FormBuilder, Validators, ControlValueAccessor, NG_VALUE_ACCESSOR, FormControl, NG_VALIDATORS } from '@angular/forms';
import { Address } from 'app/model/address/address.interface';
@Component({
selector: 'app-address',
templateUrl: './address.component.html',
styleUrls: ['./address.component.scss'],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: AddressComponent,
multi: true
},
{
provide: NG_VALIDATORS,
useExisting: forwardRef(() => AddressComponent),
multi: true,
}
]
})
export class AddressComponent implements OnInit, ControlValueAccessor, Validators {
public addressForm: FormGroup;
private _address: any = {};
istoched = false;
constructor(
private fb: FormBuilder,
) { }
ngOnInit() {
this.addressForm = this.fb.group({
address1: ['', [Validators.required]],
address2: [''],
address3: [''],
country: ['', [Validators.required]],
state: [''],
city: ['', [Validators.required]],
zip: [''],
});
}
propagateChange = (_: any) => { };
writeValue(address: Address) {
this._address = address;
if (address) {
this.addressForm.setValue({
address1: address.address1,
address2: address.address2,
address3: address.address3,
country: address.country,
state: address.state,
city: address.city,
zip: address.zip,
});
}
}
registerOnChange(fn: any) {
this.addressForm.valueChanges.subscribe(() => {
fn(this.addressForm.value);
});
}
registerOnTouched(fn: any) {
this.propagateChange = fn;
}
public validate(formControl: FormControl) {
let isValid = true;
Object.keys(this.addressForm.controls).forEach((control) => {
if (this.addressForm.controls[control] instanceof FormControl) {
if (!(<FormControl>this.addressForm.controls[control]).valid) {
isValid = false;
if (this.istoched) {
this.addressForm.controls[control].markAsTouched();
}
}
}
});
this.istoched = true;
if (isValid) {
return null;
} else {
return {
primaryContactError: {
valid: false,
}
};
}
}
}
While clicking on the submit button of customer form, if any required field is not filled, it should show required error.