Reputation: 3535
I can't seem to discover the way to reference form controls in my component template.
Although I am passing the form group (from the <form>
tag) into this child component, I know I have a valid FormGroup object structure, because I can see the raw output from console.log(this.f.getRawValue()):
abn:""
addressLine1:""
addressLine2:""
addressLine3:""
addressPostcode:""
addressState:""
addressSuburb:""
contactEmail:""
contactFax:""
contactMobile:""
contactPhone:""
fcApprovals:Array(1)
0:
approvalNumber:""
description:""
expires:Sat Mar 03 2018 17:07:50 GMT+1100 (AEDT) {}
This is exactly the object structure I expected coming into the form html
<div *ngIf="f.get('fcApprovals')" [formGroup]="f" class="block-container center form-panel not-full-width">
<div class="panel-title">Approvals</div>
<div class="block-container center not-full-width" formArrayName="fcApprovals"
*ngFor="let approval of f.get('fcApprovals').controls; let i = index;">
<div class="block-element pad-me-up" [formGroupName]="i">
<div class="form-group" [ngClass]="{
'has-danger': description.invalid && description.dirty,
'has-success': description.valid && description.dirty}">
<input type="text" class="form-control" placeholder="Description" name="description"
formControlName="description" required/>
<div *ngIf="description.untouched || description.valid"
class="ui message">Description
</div>
<div *ngIf="description.dirty || description.touched">
<div *ngIf="description.errors.required"
class="ui error message">Description is required
</div>
</div>
<div class="icon description"></div>
</div>
The page goes on after this, but the above is what's important. The problem is that the reference "description" is undefined.
I have tried the following referening:
i.description
approval.description
fcApprovals[i].description
fcApprovals[i].control.description
and many more. Nothing seems to work. The error I get is:
ApprovedComponent.html:6 ERROR TypeError: Cannot read property 'invalid' of undefined
at Object.eval [as updateDirectives] (ApprovedComponent.html:8)
at Object.debugUpdateDirectives [as updateDirectives] (core.js:14651)
at checkAndUpdateView (core.js:13798)
at callViewAction (core.js:14149)
at execEmbeddedViewsAction (core.js:14107)
at checkAndUpdateView (core.js:13799)
at callViewAction (core.js:14149)
at execEmbeddedViewsAction (core.js:14107)
at checkAndUpdateView (core.js:13799)
at callViewAction (core.js:14149)
The error references the FormArray iteration just above the description reference, but the property 'invalid' first appears on description.
So, how do you reference these controls and their values?
Upvotes: 1
Views: 1131
Reputation: 3535
The answer is: approval.get('description')
I happened to stumble across a reference to this in an unrelated post. It's definitely a good candidate for the documentation, because there's no way I would have guessed that!
And the key was in my typescript component.
return this.fb.group({
'description': ['', Validators.required],
'approvalNumber': ['', Validators.required],
'expires': new Date(),
});
I actually put the three controls into a group, so I was iterating a FormArray containing one or more FormGroups - golly!
What's a bit odd though, it appears that the errors object is not on the same path, because:
approval.get('description').errors.required
returns "Cannot read property 'required' of null"
I've spent about 9 hours on this!
Upvotes: 1