I work with reactive forms in my angular-project and i use mat-country-select for displaying countries in select in my child FormComponent.
<mat-select-country class="full-width"
[formControl]="form.controls.country"
[required]="true"
appearance="outline"
[itemsLoadSize]="0"
[value]="DEFAULT_COUNTRY"
label="Choose country">
</mat-select-country>
I try to make modal dialog window for updating an Player in parent PlayerComponet, that has such structure as below.
export interface Player extends BaseResponse {
lastName: string;
firstName: string;
dateOfBirth: Date;
country: string;
height: number;
weight: number;
position: string;
jerseyNumber: number;
teamName: string;
teamId?: string | null;
photoPath?: string | null;
}
in PlayerComponent before open update dialog window, i should initialize and pass form to my FormComponent
export class PlayersComponent implements OnInit {
countries: Country[] = COUNTRIES;
playerActionsForm!: FormGroup<PlayerActionsForm>;
fillUpdatePlayerForm(player: Player) {
this.playerActionsForm.controls.id.setValue(player.id);
this.playerActionsForm.controls.firstName.setValue(player.firstName);
this.playerActionsForm.controls.lastName.setValue(player.lastName);
this.playerActionsForm.controls.birthDay.setValue(player.dateOfBirth);
const country = this.countries.find(
(country) => country.name === player.country,
);
this.playerActionsForm.controls.country.setValue(country ? country : null);
this.playerActionsForm.controls.height.setValue(player.height);
this.playerActionsForm.controls.weight.setValue(player.weight);
this.selectTeams$
.pipe(
map((teams) => teams?.find((team) => team.id === player.teamId)),
take(1),
untilDestroyed(this),
)
.subscribe((team) => {
this.playerActionsForm.controls.team.setValue(team ? team : null);
});
this.playerActionsForm.controls.jerseyNumber.setValue(player.jerseyNumber);
this.playerActionsForm.controls.position.setValue(player.position);
this.playerActionsForm.controls.experiences.setValue([]);
}
initializeActionsForm() {
this.playerActionsForm = new FormGroup<PlayerActionsForm>({
id: new FormControl(''),
firstName: new FormControl('', [
Validators.required,
Validators.pattern(NAME_PATTERN),
]),
lastName: new FormControl('', [
Validators.required,
Validators.pattern(NAME_PATTERN),
]),
birthDay: new FormControl(null, [
Validators.required,
dateValidator(moment().subtract(18, 'years').toDate(), 'max'),
]),
country: new FormControl(null, Validators.required),
height: new FormControl(1.01, [
Validators.required,
Validators.min(1.01),
]),
weight: new FormControl(50.01, [
Validators.required,
Validators.min(50.01),
]),
team: new FormControl(null),
position: new FormControl('', Validators.required),
jerseyNumber: new FormControl(0, [
Validators.required,
Validators.min(0),
]),
experiences: new FormArray<FormGroup<PlayerExperienceForm>>([]),
});
}
ngOnInit(): void {
this.initializeActionsForm();
}
I try to use viewChild in order to get Input property of mat-country-select [Countries] but it does not work. Now i use my predefined array COUNTRIES, that had been manually created. But i need solution, that can easily get a certain country by name without manually created constants
2
Answers
Have you tried using data binding on the mat select?
You can import the countries from country
After install material-angular/countries
You can in your component
NOTE: If you want to use in your .html you need declare a variable in your .ts
Well, when we want to assig to a FormControl a value that it’s not the showed, sometimes we can take the approach of use ngModel
A simple
makes the same that a formControl. See that ngModel is the value of the formControl, and when change we makes a setValue
Well, we want assign to the formControl the whole object. so
NOTE: You can use patchValue or setValue to "fill" the formGroup (setValue need all the properties, but patchValue not)
NOTE 2: If only want to asig the countryName to the formControl