title: Angular2 Quickstart Tutorial Breaking Karma Tests - "Can't bind to 'ngModel' since it isn't a known property of 'input'."
body: <p>I am following the official Angular "Hero" Quickstart Tutorial whilst trying to TDD it.</p>
  
  <p><a href="https://angular.io/docs/ts/latest/tutorial/toh-pt1.html" rel="noreferrer">https://angular.io/docs/ts/latest/tutorial/toh-pt1.html</a></p>
  
  <p>As soon as I get to the step to replace: </p>
  
  <pre><code>&lt;input value="{{hero.name}}" placeholder="name"&gt;
  </code></pre>
  
  <p>with</p>
  
  <pre><code>&lt;input [(ngModel)]="hero.name" placeholder="name"&gt;
  </code></pre>
  
  <p>my Karma test runner throws the following error:</p>
  
  <p><strong>Error: Template parse errors:
      Can't bind to 'ngModel' since it isn't a known property of 'input'. ("
                  
                      name: 
                      ][(ngModel)]="hero.name" placeholder="name">
                   
          "): AppComponent@6:23
      Expected undefined to be defined.</strong></p>
  
  <p>However, the application works as expected and I see no errors in the console. (And I'm fairly confident I followed the tutorial correctly, can't see any typos etc)</p>
  
  <p>My app.components.ts looks like:</p>
  
  <pre><code>import { Component } from '@angular/core';
  
  export class Hero {
      id: number;
      name: string;
  }
  
  @Component({
      selector: 'my-app',
      template: `
              &lt;h1&gt;{{title}}&lt;/h1&gt;
              &lt;h2&gt;{{hero.name}} details!&lt;/h2&gt;
              &lt;div&gt;&lt;label&gt;id: &lt;/label&gt;{{hero.id}}&lt;/div&gt;
              &lt;div&gt;
                  &lt;label&gt;name: &lt;/label&gt;
                  &lt;input [(ngModel)]="hero.name" placeholder="name"&gt;
              &lt;/div&gt;
      `
  })
  
  export class AppComponent {
      title = 'Tour of Heroes';
      hero: Hero = {
          id: 1,
          name: 'Windstorm'
      };
  }
  </code></pre>
  
  <p>My app.module looks like: </p>
  
  <pre><code>import { NgModule }      from '@angular/core';
  import { BrowserModule } from '@angular/platform-browser';
  import { AppComponent }   from './app.component';
  import { FormsModule }   from '@angular/forms';
  
  @NgModule({
    imports:      [ BrowserModule, FormsModule],
    declarations: [ AppComponent],
    bootstrap:    [ AppComponent ]
  })
  export class AppModule { }
  </code></pre>
  
  <p>Karma works fine as soon as I remove ngModel from the template, and as I said before the actual app is behaving as expected. I can't seem to find any information relating to my problem after extensive googling :(</p>
  
  <p>My karma.config is the standard quickstart one:</p>
  
  <pre><code>// #docregion
  module.exports = function(config) {
  
    var appBase    = 'app/';       // transpiled app JS and map files
    var appSrcBase = 'app/';       // app source TS files
    var appAssets  = 'base/app/'; // component assets fetched by Angular's compiler
  
    var testBase    = 'testing/';       // transpiled test JS and map files
    var testSrcBase = 'testing/';       // test source TS files
  
    config.set({
      basePath: '',
      frameworks: ['jasmine'],
      plugins: [
        require('karma-jasmine'),
        require('karma-chrome-launcher'),
        require('karma-jasmine-html-reporter'), // click "Debug" in browser to see it
        require('karma-htmlfile-reporter') // crashing w/ strange socket error
      ],
  
      customLaunchers: {
        // From the CLI. Not used here but interesting
        // chrome setup for travis CI using chromium
        Chrome_travis_ci: {
          base: 'Chrome',
          flags: ['--no-sandbox']
        }
      },
      files: [
        // System.js for module loading
        'node_modules/systemjs/dist/system.src.js',
  
        // Polyfills
        'node_modules/core-js/client/shim.js',
        'node_modules/reflect-metadata/Reflect.js',
  
        // zone.js
        'node_modules/zone.js/dist/zone.js',
        'node_modules/zone.js/dist/long-stack-trace-zone.js',
        'node_modules/zone.js/dist/proxy.js',
        'node_modules/zone.js/dist/sync-test.js',
        'node_modules/zone.js/dist/jasmine-patch.js',
        'node_modules/zone.js/dist/async-test.js',
        'node_modules/zone.js/dist/fake-async-test.js',
  
        // RxJs
        { pattern: 'node_modules/rxjs/**/*.js', included: false, watched: false },
        { pattern: 'node_modules/rxjs/**/*.js.map', included: false, watched: false },
  
        // Paths loaded via module imports:
        // Angular itself
        { pattern: 'node_modules/@angular/**/*.js', included: false, watched: false },
        { pattern: 'node_modules/@angular/**/*.js.map', included: false, watched: false },
  
        { pattern: 'systemjs.config.js', included: false, watched: false },
        { pattern: 'systemjs.config.extras.js', included: false, watched: false },
        'karma-test-shim.js',
  
        // transpiled application &amp; spec code paths loaded via module imports
        { pattern: appBase + '**/*.js', included: false, watched: true },
        { pattern: testBase + '**/*.js', included: false, watched: true },
  
  
        // Asset (HTML &amp; CSS) paths loaded via Angular's component compiler
        // (these paths need to be rewritten, see proxies section)
        { pattern: appBase + '**/*.html', included: false, watched: true },
        { pattern: appBase + '**/*.css', included: false, watched: true },
  
        // Paths for debugging with source maps in dev tools
        { pattern: appSrcBase + '**/*.ts', included: false, watched: false },
        { pattern: appBase + '**/*.js.map', included: false, watched: false },
        { pattern: testSrcBase + '**/*.ts', included: false, watched: false },
        { pattern: testBase + '**/*.js.map', included: false, watched: false }
      ],
  
      // Proxied base paths for loading assets
      proxies: {
        // required for component assets fetched by Angular's compiler
        "/app/": appAssets
      },
  
      exclude: [],
      preprocessors: {},
      // disabled HtmlReporter; suddenly crashing w/ strange socket error
      reporters: ['progress', 'kjhtml'],//'html'],
  
      // HtmlReporter configuration
      htmlReporter: {
        // Open this file to see results in browser
        outputFile: '_test-output/tests.html',
  
        // Optional
        pageTitle: 'Unit Tests',
        subPageTitle: __dirname
      },
  
      port: 9876,
      colors: true,
      logLevel: config.LOG_INFO,
      autoWatch: true,
      browsers: ['Chrome'],
      singleRun: false
    })
  }
  </code></pre>
  
  <p>Can anyone help me?</p>