I am running into some issues with trying to use FormBuilder
in my Angular app and how I can set the default values in the form based on my ngModel
data.
In my class, I have the following code:
form: FormGroup;
constructor(
private fb: FormBuilder,
) { }
ngOnInit() {
this.form = this.fb.group({
category: ['', [Validators.required]],
quantity: [1, [Validators.required]],
size: ['', [Validators.required]],
title: ['', [Validators.required]],
});
}
When I look at the {{ form.value | json }}
in my template, it shows the original values with the empty values. So I decided to try to set the default values in the FormBuilder group like this:
this.form = this.fb.group({
category: [this.item.category, [Validators.required]],
quantity: [this.item.quantity, [Validators.required]],
size: [this.item.size, [Validators.required]],
title: [this.item.title, [Validators.required]],
});
But I am given these errors:
ERROR Error: formGroup expects a FormGroup instance.
ERROR TypeError: Cannot read properties of undefined (reading 'category')
ERROR TypeError: Cannot read properties of undefined (reading 'value')
This is my template for the form:
<form [formGroup]="form">
<ion-item lines="none">
<ion-label position="stacked">Category</ion-label>
<ion-select [(ngModel)]="item.category" [ngModelOptions]="{standalone: true}">
<ion-select-option *ngFor="let category of categories" [value]="category">
{{ category }}
</ion-select-option>
</ion-select>
</ion-item>
<ion-item lines="none">
<ion-label position="stacked">Title</ion-label>
<ion-input [(ngModel)]="item.title" [ngModelOptions]="{standalone: true}"></ion-input>
</ion-item>
<ion-item lines="none">
<ion-label position="stacked">Size</ion-label>
<ion-input [(ngModel)]="item.size" [ngModelOptions]="{standalone: true}"></ion-input>
</ion-item>
<ion-item lines="none">
<ion-label position="stacked">Quantity</ion-label>
<ion-input type="number" [(ngModel)]="item.quantity" [ngModelOptions]="{standalone: true}"></ion-input>
</ion-item>
</form>
Any thoughts what is wrong with my approach and how I can get the default values from my this.item
to appear in the form?
Zerospi, the problem is that you create the form before you has data in your variable "item" - this is the reason you don't see the value
NEVER Mix together Reactive forms and Template-Driven (ngModel)
The use [(ngModel)]="variable" [ngModelOptions]="{standalone: true}
it's ONLY to get an input that not belong to the FormGroup.
e.g you can has a "checkbox" to show a new input. Some like
movil:boolean=false;
form=new FormGroup({
phone:new FormControl()
mobile:new FormControl()
})
<form [formGroup]="form">
Phone<input formControlName="phone">
<input type="checkbox" [(ngModel)]="movil"
[ngModelOptions]="{standalone:true}">Mobile
<input *ngIf="movil" formControlName="mobile">
</form>
Well, really we use
<input type="checkbox" [ngModel]="movil"
(ngModelChange)="movil=$event;!$event && form.get('mobile').setValue('')
[ngModelOptions]="{standalone:true}">Mobile
To "clean" the FormControl "mobile" if we uncheck
How control a FormGroup?
In general we can have a function in the way
getFromGroup(data:any=null)
{
data=data || {phone:'',mobile:''}
return this.fb.group({
phone:[data.phone,Validators.required]
mobile:data.mobile
}
}
And use
this.form=this.getFormGroup(this.item) //if we have an object "this.item"
this.form=this.getFormGroup() //if we want an empty Form
Another approach is create the form an use patchValue()
this.form=this.fb.group({
phone:['',Validators.required]
mobile:''
}
this.form.patchValue(this.item)
To avoid initial errors (e.g. we create the form after a call to an API), sometimes is util use some like
<form *ngIf="form" [formGroup]="form">
...
</form>
Remember that a FormControl is disabled, don't showed in form.value, you need use form.getRawValue()