Can't bind to 'formGroup' since it isn't a known property of 'form'

The situation

I am trying to make what should be a very simple form in my Angular application, but no matter what, it never works.

The Angular version

Angular 2.0.0 RC5

The error

Can't bind to 'formGroup' since it isn't a known property of 'form'

Enter image description here

The code

The view

<form [formGroup]="newTaskForm" (submit)="createNewTask()">
   <div class="form-group">
      <label for="name">Name</label>
      <input type="text" name="name" required>
   </div>
   <button type="submit" class="btn btn-default">Submit</button>
</form>

The controller

import { Component } from '@angular/core';
import { FormGroup, FormControl, Validators, FormBuilder }  from '@angular/forms';
import {FormsModule,ReactiveFormsModule} from '@angular/forms';
import { Task } from './task';

@Component({
    selector: 'task-add',
    templateUrl: 'app/task-add.component.html'

})
export class TaskAddComponent {

    newTaskForm: FormGroup;

    constructor(fb: FormBuilder)
    {
        this.newTaskForm = fb.group({
            name: ["", Validators.required]
        });
    }

    createNewTask()
    {
        console.log(this.newTaskForm.value)
    }
}

The ngModule

import { NgModule }      from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule }   from '@angular/forms';

import { routing }        from './app.routing';
import { AppComponent }  from './app.component';
import { TaskService } from './task.service'

@NgModule({
    imports: [
        BrowserModule,
        routing,
        FormsModule
    ],
    declarations: [ AppComponent ],
    providers: [
        TaskService
    ],
    bootstrap: [ AppComponent ]
})
export class AppModule { }

The question

Why am I getting that error? Am I missing something?


Solution 1:

RC6/RC7/Final release FIX

To fix this error, you just need to import ReactiveFormsModule from @angular/forms in your module. Here's the example of a basic module with ReactiveFormsModule import:

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { AppComponent }  from './app.component';

@NgModule({
    imports: [
        BrowserModule,
        FormsModule,
        ReactiveFormsModule
    ],
    declarations: [
        AppComponent
    ],
    bootstrap: [AppComponent]
})

export class AppModule { }

To explain further, formGroup is a selector for directive named FormGroupDirective that is a part of ReactiveFormsModule, hence the need to import it. It is used to bind an existing FormGroup to a DOM element. You can read more about it on Angular's official docs page.

RC5 FIX

You need to import { REACTIVE_FORM_DIRECTIVES } from '@angular/forms' in your controller and add it to directives in @Component. That will fix the problem.

After you fix that, you will probably get another error because you didn't add formControlName="name" to your input in form.

Solution 2:

Angular 4 in combination with feature modules (if you are for instance using a shared-module) requires you to also export the ReactiveFormsModule to work.

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';

@NgModule({
  imports:      [
    CommonModule,
    ReactiveFormsModule
  ],
  declarations: [],
  exports: [
    CommonModule,
    FormsModule,
    ReactiveFormsModule
  ]
})
export class SharedModule { } 

Solution 3:

Ok after some digging I found a solution for "Can't bind to 'formGroup' since it isn't a known property of 'form'."

For my case, I've been using multiple modules files, i added ReactiveFormsModule in app.module.ts

 import { FormsModule, ReactiveFormsModule } from '@angular/forms';`

@NgModule({
  declarations: [
    AppComponent,
  ]
  imports: [
    FormsModule,
    ReactiveFormsModule,
    AuthorModule,
],
...

But this wasn't working when I use a [formGroup] directive from a component added in another module, e.g. using [formGroup] in author.component.ts which is subscribed in author.module.ts file:

import { NgModule }       from '@angular/core';
import { CommonModule }   from '@angular/common';
import { AuthorComponent } from './author.component';

@NgModule({
  imports: [
    CommonModule,
  ],
  declarations: [
    AuthorComponent,
  ],
  providers: [...]
})

export class AuthorModule {}

I thought if i added ReactiveFormsModule in app.module.ts, by default ReactiveFormsModule would be inherited by all its children modules like author.module in this case... (wrong!). I needed to import ReactiveFormsModule in author.module.ts in order to make all directives to work:

...
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
...

@NgModule({
  imports: [
    ...,
    FormsModule,    //added here too
    ReactiveFormsModule //added here too
  ],
  declarations: [...],
  providers: [...]
})

export class AuthorModule {}

So, if you are using submodules, make sure to import ReactiveFormsModule in each submodule file. Hope this helps anyone.

Solution 4:

I have encountered this error during unit testing of a component (only during testing, within application it worked normally). The solution is to import ReactiveFormsModule in .spec.ts file:

// Import module
import { ReactiveFormsModule } from '@angular/forms';

describe('MyComponent', () => {
    beforeEach(async(() => {
        TestBed.configureTestingModule({
            declarations: [MyComponent],
            imports: [ReactiveFormsModule],  // Also add it to 'imports' array
        })
        .compileComponents();
    }));
});