Reputation: 541
I have a big reactive form, and I want to break up the template into child components.
The child component is not pulling through default form data from Parent.
Initially I forgot to bind the child component formGroup attribute to the parent's FormGroup. I fixed this, put the issue persists.
I believe it may have something to do with dealing with nested FormGroups. I changed:
<app-account-settings [formGroup]="settingsForm" [isBusiness]="isBusiness"
[user]="user"></app-account-
settings>
to:
<app-account-settings [formGroup]="accountSettings" [isBusiness]="isBusiness"
[user]="user"></app-account-
settings>
This did not work.
Parent component:
export class SettingsPage implements OnInit {
public user: any;
public isBusiness: boolean;
public settingsForm: FormGroup
constructor(
private config: Configuration,
private profileProvider: ProfileProvider,
private authentication: AuthenticationProvider,
private route: ActivatedRoute) {
}
ngOnInit() {
this.isBusiness = this.authentication.isBusiness()
this.user = this.route.snapshot.data.userProfile;
this.settingsForm = new FormGroup({
accountSettings: new FormGroup({
username: new FormControl(this.user.username),
email: new FormControl(this.user.email),
password: new FormControl(this.user.password)
})
...more form groups
})
})
Parent template:
<form [formGroup]="settingsForm" (ngSubmit)="onSubmit()">
<app-account-settings [formGroup]="settingsForm" [isBusiness]="isBusiness"
[user]="user"></app-account-
settings>
Child component:
@Component({
selector: 'app-account-settings',
templateUrl: './account-settings.component.html',
styleUrls: ['./account-settings.component.scss']
})
export class AccountSettingsComponent implements OnInit {
@Input('isBusiness') isBusiness: boolean;
@Input('user') user: any;
@Input('id') id: any
constructor(private controlContainer: ControlContainer) { }
ngOnInit() {
console.log('isBusiness', this.isBusiness) // successfully logs value
console.log('user', this.user) // successfully logs value
}
}
Child template:
<ng-container formGroup="controlContainer.control">
<div class="row settings-block">
<div class="col-md-12" >
<div class="box title">
<div class="row" >
<div class="col-md-12" >
<h1>Account</h1>
</div>
</div>
</div>
<div class="box settings">
<div class="row">
<div class="col-md-4">
<h1>Username</h1>
<input type="text" placeholder="Username" formControlName="username" [value]="user.username">
</div>
<div class="col-md-4">
<h1>Email Address</h1>
<input type="email" placeholder="Email Address" formControlName="email" [value]="user.email || ''">
</div>
<div class="col-md-4">
<h1>New Password</h1>
<input type="password" placeholder="Enter New Password" formControlName="password" value="">
</div>
</div>
</div>
</div>
</ng-container>
I expected that the default FormControl values to be passed through to the input elements of the child component. This does not happen.
Upvotes: 0
Views: 678
Reputation: 3342
Try changing <ng-container formGroup="controlContainer.control">
to <ng-container [formGroup]="controlContainer.control">
. When you are specifying an attribute with square brackets (Property binding), Angular interprets the right side as JS object, but when you don't use them, angular is not evaluating it and thinks it's just a string.
Upvotes: 0
Reputation: 5470
Easiest way to solve this issue without implementing ControlValueAccessor
is to use viewProviders
on your child template.
Remove [formGroup]="settingsForm"
from your <app-account-settings>
<form [formGroup]="settingsForm" (ngSubmit)="onSubmit()">
<app-account-settings [isBusiness]="isBusiness"
[user]="user"></app-account-settings>
Then your child component add viewProviders
property to component: (Don't need to inject ControlContainer
on your constructor either, so you can remove it.)
@Component({
selector: 'app-account-settings',
templateUrl: './account-settings.component.html',
styleUrls: ['./account-settings.component.scss'],
viewProviders: [ { provide: ControlContainer, useExisting: FormGroupDirective }]
})
Then you can just use your formGroup="accountSettings"
on your child components
Here's an example on stackblitz for reference: https://stackblitz.com/edit/angular-ruxfee
Upvotes: 1