4
votes

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?

1

1 Answers

5
votes

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"