259
votes

I keep getting this error while using TypeScript's Angular2-forms framework:

There is no directive with "exportAs" set to "ngForm"

Here's my code

project dependencies :

  "dependencies": {
    "@angular/common": "2.0.0-rc.6",
    "@angular/compiler": "2.0.0-rc.6",
    "@angular/core": "2.0.0-rc.6",
    "@angular/forms": "2.0.0-rc.6",
    "@angular/http": "2.0.0-rc.6",
    "@angular/platform-browser": "2.0.0-rc.6",
    "@angular/platform-browser-dynamic": "2.0.0-rc.6",
    "@angular/router": "3.0.0-rc.2",
    "ng2-bootstrap": "^1.1.1",
    "reflect-metadata": "^0.1.8",
    "core-js": "^2.4.0",
    "es6-module-loader": "^0.17.8",
    "rxjs": "5.0.0-beta.11",
    "systemjs": "0.19.27",
    "zone.js": "0.6.17",
    "jquery": "3.0.0",
  }

And this is the Login Template :

<form #loginForm="ngForm" (ng-submit)="authenticate(loginForm.value)">
</form>

...and the Login Component :

import { Component } from '@angular/core';
import {Http, Headers}  from '@angular/http';
@Component({
    moduleId: module.id,
    selector: 'login-cmp',
    templateUrl: 'login.component.html'
})
export class LoginComponent {
  constructor($http: Http) {
    this.$http = $http;
  }
  authenticate(data) {
   ... 
  }
}

I have this Error :

zone.js?1474211973422:484 Unhandled Promise rejection: Template parse errors:    
There is no directive with "exportAs" set to "ngForm" ("
            <form [ERROR ->]#loginForm="ngForm" 
(ngsubmit)="authenticate(loginForm.value)">
26

26 Answers

532
votes
import { FormsModule }   from '@angular/forms';

@NgModule({
  imports: [
             BrowserModule,

             FormsModule      //<----------make sure you have added this.
           ],
  ....
})
57
votes

You have to import FormsModule into not only the root AppModule, but also into every subModule that uses any angular forms directives.

// SubModule A

import { CommonModule } from '@angular/common';
import { FormsModule }   from '@angular/forms';

@NgModule({
  imports: [
    CommonModule,
    FormsModule      //<----------make sure you have added this.
  ],
  ....
})
49
votes

I know this is a Old post, but i would like to share my solution. I have added "ReactiveFormsModule" in imports[] array to resolve this error

Error: There is no directive with "exportAs" set to "ngForm" ("

Fix:

module.ts

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

 imports: [
    BrowserModule,
    FormsModule , 
    ReactiveFormsModule
  ],
15
votes
import { FormsModule }   from '@angular/forms';

@NgModule({
  imports: [FormsModule],
  ...
})
9
votes

(Just in case someone else is blind like me) form FTW! Make sure to use <form> tag

wont work:

<div (ngSubmit)="search()" #f="ngForm" class="input-group">
    <span class="input-group-btn">
      <button class="btn btn-secondary" type="submit">Go!</button>
    </span>
    <input type="text" ngModel class="form-control" name="search" placeholder="Search..." aria-label="Search...">
</div>

works like charm:

 <form (ngSubmit)="search()" #f="ngForm" class="input-group">
            <span class="input-group-btn">
              <button class="btn btn-secondary" type="submit">Go!</button>
            </span>
            <input type="text" ngModel class="form-control" name="search" placeholder="Search..." aria-label="Search...">
</form>
9
votes

In case a name is assigned like this:

#editForm="testForm"

... the exportAs has to be defined in the component decorator:

selector: 'test-form',
templateUrl: './test-form.component.html',
styleUrls: ['./test-form.component.scss'],
exportAs: 'testForm'
5
votes

check whether you import FormsModule. There's no ngControl in the new forms angular 2 release version. you have to change your template to as an example

<div class="row">
    <div class="form-group col-sm-7 col-md-5">
        <label for="name">Name</label>
        <input type="text" class="form-control" required
               [(ngModel)]="user.name"
               name="name" #name="ngModel">
        <div [hidden]="name.valid || name.pristine" class="alert alert-danger">
            Name is required
        </div>
    </div>
</div>
4
votes

I faced this issue, but none of the answers here worked for me. I googled and found that FormsModule not shared with Feature Modules

So If your form is in a featured module, then you have to import and add the FromsModule there.

Please ref: https://github.com/angular/angular/issues/11365

4
votes

Two Things you have to care..

  1. If you using the sub module, you have to import the FormModule in that sub module.

            **imports:[CommonModule,HttpModule,FormsModule]**
    
  2. you have to exports the FormModule in the module

        **exports:[FormsModule],**
    

    so together it looks like imports:[CommonModule,HttpModule,FormsModule], exports:[FormsModule],

  3. in Top u have to import the FormsModule

    import {FormsModule} from '@angular/forms';


if you are using only the app.module.ts then

no need to export.. only import required

3
votes

In addition to import the form module in login component ts file you need to import NgForm also.

import { NgForm } from '@angular/forms';

This resolved my issue

3
votes

This

<div #myForm="ngForm"></div>

Also causes the error and can be fixed by including the ngForm directive.

<div ngForm #myForm="ngForm"></div>
3
votes

I've come to this same question over & over again, also due to same reason. So let me answer this by saying what wrong I was doing. Might be helpful for someone.

I was creating component via angular-cli by command

ng g c components/something/something

What it did, was created the component as I wanted.

Also, While creating the component, it added the component in the App Module's declarations array.

If this is the case, please remove it. And Voila! It might work.

2
votes

This error also occurs if you are trying to write a unit test case in angular using jasmine.

The basic concept of this error is to import FormsModule. Thus, in the file for unit tests, we add imports Section and place FormsModule in that file under

    TestBed.configureTestingModule
    For eg: 
    TestBed.configureTestingModule({
        declarations: [ XYZComponent ],
        **imports: [FormsModule]**,
    }).compileComponents();
1
votes
import { FormsModule,ReactiveFormsModule }from'@angular/forms';

imports:[
    BrowserModule.withServerTransition({ appId: 'ng-cli-universal' }),
    HttpClientModule,
    FormsModule,
    ReactiveFormsModule/*This one in particular*/,...
],

in app.module.ts to permanently solve errors like "cannot bind [formGroup] or no directive with export as".

1
votes

In my case, I forgot to add my component in the Declaration array of app.module.ts, and voila! the issue was fixed.

1
votes

Another item check:

Make sure you component is added to the declarations array of @NgModule in app.module.ts

@NgModule({
declarations: [
    YourComponent,
],

When running the ng generate component command, it does not automatilly add it to app.module.

1
votes

Simple if you have not import module then import and declare import { FormsModule } from '@angular/forms';

and if you did then you just need to remove ** formControlName='whatever' ** from input fields.

module.ts

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

 imports: [
    BrowserModule,
    FormsModule, 
    ReactiveFormsModule
  ],
1
votes

Yes i faced same problem...I did above all things but not worked. This one solved my problem. Because we are using angular 'with' in strict mode.

in app.module.ts add this code

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

imports: [
    BrowserModule,
    FormsModule, 
    ReactiveFormsModule
],

and which file you are using NgForm in .html file

<form #form="ngForm" (ngSubmit)="loginSubmit(form);">
</form>

and in .ts file

import { NgForm } from '@angular/forms';
@Component({
  selector: 'app-login-page',
  templateUrl: './login-page.component.html',
  styleUrls: ['./login-page.component.scss']
})
export class LoginPageComponent implements OnInit {
  NgForm=NgForm;//this one solve my problem...initialization and declaration
}
0
votes

You must import the FormsModule and then place it in the section of imports.

import { FormsModule } from '@angular/forms';
0
votes

You should terminate app with ctrl+c and re run it with ng serve, if you did not include FormsModule into you app.module file imports array, and then added it later, angular does not know it, it does not re-scan modules, you should restart app so angular could see that new module is included, after what it will included all features of template drive approach

0
votes

In my case I had to remove the ngNoForm attribute from my <form> tag.

If you you want to import FormsModule in your application but want to skip a specific form, you can use the ngNoForm directive which will prevent ngForm from being added to the form

Reference: https://www.techiediaries.com/angular-ngform-ngnoform-template-reference-variable/

0
votes

I just moved routing modules i.e. say ARoutingModule above FormsModule and ReactiveFormsModule and after CommonModule in imports array of modules.

0
votes

Just import the correct module,

"FormsModule"

import { FormsModule } from "@angular/forms";
@NgModule({
  imports: [
    BrowserModule,
    FormsModule //<---.
  ],
  ....
})
0
votes

just giving this as a reference, becos this worked for newer angular versions There is no directive with “exportAs” set to “ngForm”

0
votes

Agree with the solution provided by @micronyks but that hold's true if you've simple application which doesn't have many modules within it. Otherwise, we need to add in similar way to module where we're using that <form #loginForm="ngForm"> element and adding below code inside that module if you don't want to expose it to all modules or whole application.

import FormsModule from '@angular/forms';
@NgModule{
imports: [FormsModule],
}
-1
votes

You must declare FormsModule and must declare also the Compoponent

declarations: [
   YourComponent  -->
  ],
  imports: [
    BrowserModule,
    FormsModule, -->

    
  ],