title: Angular 4 - There is no directive with "exportAs" set to "ngForm"
body: <p>I've seen answers to this question around stackoverflow that deal with how the app is configured. However I am pretty sure I've configured it correctly as the app runs just fine but my <strong>super simple Karma test fails</strong>.</p>
  
  <p>Here is my app.module.ts:</p>
  
  <pre><code>import { NgModule } from '@angular/core';
  
  import { BrowserModule } from '@angular/platform-browser';
  import { FormsModule } from '@angular/forms';
  //import { AppRoutingModule } from './app-routing.module';
  import { HttpClientModule } from '@angular/common/http';
  
  import { AppComponent } from './app.component';
  import { LoginFormComponent } from './login-form/login-form.component';
  
  import { ManagerService } from './manager.service';
  // import { AuthinterceptorService } from './authinterceptor.service';
  
  
  @NgModule({
    imports: [
      BrowserModule,
      FormsModule,
  //    AppRoutingModule,
      HttpClientModule,
    ],
    declarations: [
      AppComponent,
      LoginFormComponent
    ],
    // TODO use interceptor to send oauth token
    providers: [
      ManagerService
      // , {provide: HTTP_INTERCEPTORS, useClass: AuthinterceptorService, multi: true}
      ],
    bootstrap: [AppComponent]
  })
  export class AppModule { }
  </code></pre>
  
  <p>Here is the login-form.component.ts</p>
  
  <pre><code>import { Component, OnInit } from '@angular/core';
  import { HttpErrorResponse } from '@angular/common/http';
  import { FormsModule }   from '@angular/forms';
  
  import { ManagerService } from '../manager.service';
  import { Login } from './login';
  
  @Component({
    selector: 'manager-login-form',
    templateUrl: './login-form.component.html',
    styleUrls: ['./login-form.component.css']
  })
  export class LoginFormComponent implements OnInit {
  
    login = new Login('', '');
  
    submitted = false;
  
    constructor(private managerService: ManagerService) { }
  
    ngOnInit() {
    }
  
    onSubmit() {
      console.log('Submitting form');
      this.submitted = true;
      this.managerService.retrieveToken(this.login).subscribe(oauth =&gt;
          this.managerService.start(oauth).subscribe(
                    res =&gt; console.log(res),
                    (error: HttpErrorResponse) =&gt; this.processError(error)
                  )
        );
    }
  </code></pre>
  
  <p>Here is my login-form.component.html</p>
  
  <pre><code>&lt;form (ngSubmit)="onSubmit()" #loginForm="ngForm" class="form-signin"&gt;
  
      &lt;div class="form-group"&gt;
          &lt;input type="text" class="form-control" id="username" placeholder="Username" [(ngModel)]="login.username" name="username" required&gt;
      &lt;/div&gt;
      &lt;div class="form-group"&gt;
          &lt;input type="password" class="form-control" id="password" placeholder="Password" [(ngModel)]="login.password" name="password" required &gt;
      &lt;/div&gt;
  
      &lt;button type=submit class="btn btn-lg btn-primary btn-block" [disabled]="!loginForm.form.valid"&gt;Sign In&lt;/button&gt;
      &lt;input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/&gt;
  &lt;/form&gt;
  </code></pre>
  
  <p>The unit test (very simple):</p>
  
  <pre><code>import { async, ComponentFixture, TestBed } from '@angular/core/testing';
  
  import { LoginFormComponent } from './login-form.component';
  
  describe('LoginFormComponent', () =&gt; {
    let component: LoginFormComponent;
    let fixture: ComponentFixture&lt;LoginFormComponent&gt;;
  
    beforeEach(async(() =&gt; {
      TestBed.configureTestingModule({
        declarations: [ LoginFormComponent ]
      })
      .compileComponents();
    }));
  
    beforeEach(() =&gt; {
      fixture = TestBed.createComponent(LoginFormComponent);
      component = fixture.componentInstance;
      fixture.detectChanges();
    });
  
    it('should be created', () =&gt; {
      expect(component).toBeTruthy();
    });
  });
  </code></pre>
  
  <p>And my package.json for completeness:</p>
  
  <pre><code>{
    "name": "ui",
    "version": "1.0.0",
    "license": "MIT",
    "scripts": {
      "ng": "ng",
      "start": "ng serve",
      "build": "ng build",
      "test": "ng test",
      "lint": "ng lint",
      "e2e": "ng e2e"
    },
    "private": true,
    "dependencies": {
      "@angular/animations": "^4.0.0",
      "@angular/common": "^4.0.0",
      "@angular/compiler": "^4.0.0",
      "@angular/core": "^4.0.0",
      "@angular/forms": "^4.0.0",
      "@angular/http": "^4.0.0",
      "@angular/platform-browser": "^4.0.0",
      "@angular/platform-browser-dynamic": "^4.0.0",
      "@angular/router": "^4.0.0",
      "core-js": "^2.4.1",
      "rxjs": "^5.1.0",
      "zone.js": "^0.8.4",
      "angular-in-memory-web-api": "^0.3.1"
    },
    "devDependencies": {
      "@angular/cli": "1.3.1",
      "@angular/compiler-cli": "^4.0.0",
      "@angular/language-service": "^4.0.0",
      "@types/jasmine": "~2.5.53",
      "@types/jasminewd2": "~2.0.2",
      "@types/node": "~6.0.60",
      "codelyzer": "~3.0.1",
      "jasmine-core": "~2.6.2",
      "jasmine-spec-reporter": "~4.1.0",
      "karma": "~1.7.0",
      "karma-chrome-launcher": "~2.1.1",
      "karma-cli": "~1.0.1",
      "karma-coverage-istanbul-reporter": "^1.2.1",
      "karma-jasmine": "~1.1.0",
      "karma-jasmine-html-reporter": "^0.2.2",
      "protractor": "~5.1.2",
      "ts-node": "~3.0.4",
      "tslint": "~5.3.2",
      "typescript": "~2.3.3"
    }
  }
  </code></pre>
  
  <p>So along with the <code>There is no directive with "exportAs" set to "ngForm"</code> I also have <code>Can't bind to 'ngModel' since it isn't a known property of 'input'</code> for both my inputs.</p>
  
  <p>I have followed the documentation <a href="https://angular.io/guide/forms" rel="nofollow noreferrer">here</a> so no idea what the problem is. I don't have any other components except for login and app. I have the Manager Service as the only service and all my other code are just plain classes.</p>