I would like to create a form and use a new, custom component for its controls. So I created a new component and included it into the parent form. But although the parent form has a formGroup, Angular complains that it does not.
The error:
Error: formControlName must be used with a parent formGroup directive. You'll want to add a formGroup directive and pass it an existing FormGroup instance (you can create one in your class).
The parent form has:
<form [formGroup]="learningObjectForm" (ngSubmit)="onSubmit()" novalidate>
<div>
<button type="submit"
[disabled]="learningObjectForm.pristine">Save</button>
</div>
<ava-form-control [label]="'Resource'"></ava-form-control>
</form>
And in the .ts:
constructor(private fb: FormBuilder) {
this.createForm();
}
createForm() {
this.learningObjectForm = this.fb.group({
text: '',
});
}
In the custom component I have
import { Component, Input, OnInit } from '@angular/core';
@Component({
selector: 'ava-form-control',
template: ` <div>
<label>{{label}} :</label>
<input formControlName="{{name}}">
</div>
`
})
export class FormControlComponent implements OnInit {
@Input() label: string;
@Input() name: string;
constructor() {}
ngOnInit() {
if (this.name === undefined) {
// turns 'The Label' into 'theLabel'
this.name = this.label[0].toLowerCase().concat(this.label.slice(1));
this.name = this.name.split(' ').join('');
console.log(this.label, this.name);
}
}
}
I played around with the accepted answer for a long time, and never had any luck.
I had much better results implementing the ControlValueAccessor interface as shown here: https://alligator.io/angular/custom-form-control/
It's actually pretty simple, I also rigged up an Example StackBlitz
You should also be passing the
formGroup
instance along withcontrol name
to yourcustom component
. And then create aform control
under thatformGroup
in custom component. Your custom component will create the control virtually under the same formGroup that you have provided.custom.component.ts
With this your parent component can access all the form controls defined within their respective custom components.