4

I was developing a SPA in Angular2 RC1 however since the final release is out now, my organisation has decided to port the code to Angular 2 GA. While I could fix most of the broken things, I am really struggling with forms.
In my earlier code with RC1, I have used ControlGroup and Control along with FormBuilder. I am using them to do the usual form stuff like validations, adding & removing controls, etc. However now apparently they have been removed and I have no idea what has replaced them.
I tried a few other classes from API guide FormControl or FormGroup but neither hasn't really helped. I would like to know what is the replacement for above two classes.

Edit: FormControl and FormGroup have eliminated the errors in TypeScript file, however, in the markup, I get inline template:0:0 caused by: No provider for FormBuilder! error.

UPDATE: I could use FormGroup, FormControl and FormBuilder. The above error got solved by adding ReactiveFormsModule to the app.module.ts file. However, I get a error inline template:30:61 caused by: this.form._updateTreeValidity is not a function.
That specific line in the template is
<form #userForm="ngForm" (ngSubmit)="submitUser()" [formGroup]="userForm" novalidate autocomplete="off">

Any ideas?

theHeman
  • 505
  • 1
  • 6
  • 26

1 Answers1

5

Updated to current Angular (v4.0.1)

FormGroup or FormBuilder can be used instead. FormBuilder is simply a short-hand method for FormGroup. So is recommended for larger/complex forms.

The problem with the code you have shown above is that you are declaring both FormGroup and ngModel-#userForm="ngForm", which to my understanding cannot be used together- not easily anyway... I made this mistake as well.

private myForm: FormGroup;

constructor(){
    this.myForm = new FormGroup({
        name: new FormGroup({
            first: new FormControl('Nancy', Validators.required),
            last: new FormControl('Drew')
        }),
        email: new FormControl('')
    });
}

//The same thing using 'FormBuilder': (Note this would not change the template)
constructor(@Inject(FormBuilder) fb: FormBuilder) {
    this.myForm = fb.group({
        name: fb.group({
            first: ['Nancy', Validators.required],
            last: 'Drew',
        }),
        email: '',
    });
}

And your Template like so:

<form [formGroup]="myForm" novalidate autocomplete="off">
    <div formGroupName="name" novalidate autocomplete="off">
        <input type="text" formControlName="first"/>
        <input type="text" formControlName="last"/>
        <span [hidden]="myForm.controls['name'].valid">Error</span>
    </div>
    <input type="text" formControlName="email"/>
</form>

The alternative to this approach is to use Angular's Template Driven Forms, this is where you will use the [(ngModel)]="someInput"

P. Moloney
  • 721
  • 8
  • 22
  • And yet, using exactly this pattern, I get `Can't bind to 'FormControlName' since it isn't a known property of 'input'`; I had to use `"formControlName"="control-name"` (in Angular 2.0.2). Still I get that lovely constructor double-firing. – msanford Oct 24 '16 at 14:03
  • Make sure you are using the correct `FormModule imports`. See the issue raised here: [Can't bind to 'formGroup' since it isn't a known property of 'form'](http://stackoverflow.com/questions/39152071/cant-bind-to-formgroup-since-it-isnt-a-known-property-of-form) – P. Moloney Oct 24 '16 at 14:33
  • There was actually one or two issues with the code, but I have updated the answer with corrections. Thanks. – P. Moloney Oct 24 '16 at 14:57
  • Thanks for the edits. I am indeed importing `REACTIVE_FORM_DIRECTIVES` in the component (already saw that thread, but thank you for the link). I noticed there are extra single quotes inside the double quotes: is this to escape them since ng2 evals things inside `"`? – msanford Oct 24 '16 at 15:21
  • No problem. I believe formControlName takes a string as a parameter. In my code I use an array of strings to create the form- that's why I missed this the first time around. – P. Moloney Oct 24 '16 at 15:47