I'm trying to add a ngModel directive to one of the components in the angular SPA template, using an example from the angular documentation on the ngModel directive.
Here is my system configuration
C:\>npm -v
5.3.0
C:\>node -v
v8.2.1
C:\>dotnet --version
1.1.0
Both webpack --config .\webpack.config.vendor.js and webpack --config .\webpack.config.js run without any errors.
I modified the counter component from the angular SPA template (created with dotnet new angular)
counter.component.html
<h1>Counter</h1>
<p>This is a simple example of an Angular component.</p>
<p>Current count: <strong>{{ currentCount }}</strong></p>
<button (click)="incrementCounter()" type="button" class="btn btn-primary">Increment</button>
<!-- I added the following HTML tags -->
<input [(ngModel)]="name" #ctrl="ngModel" required>
<p>Value: {{ name }}</p>
<p>Valid: {{ ctrl.valid }}</p>
counter.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'counter',
templateUrl: './counter.component.html'
})
export class CounterComponent {
public currentCount = 0;
// I added this single property here
name: string = '';
public incrementCounter() {
this.currentCount++;
}
}
I get the following error when I do dotnet run (ASPNETCORE_ENVIRONMENT = "Development"), and try to load any page.
fail: Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware[0]
An unhandled exception has occurred: Call to Node module failed with error: Error: Template parse errors:
There is no directive with "exportAs" set to "ngModel" ("="button" class="btn btn-primary">Increment</button>
<input [(ngModel)]="name" [ERROR ->]#ctrl="ngModel" required>
<p>Value: {{ name }}</p>
"): ng:///AppModule/CounterComponent.html@8:30
Can't bind to 'ngModel' since it isn't a known property of 'input'. ("mentCounter()" type="button" class="btn btn-primary">Increment</button>
<input [ERROR ->][(ngModel)]="name" #ctrl="ngModel" required>
<p>Value: {{ name }}</p>
"): ng:///AppModule/CounterComponent.html@8:11
at syntaxError (C:\dotnet_core_angular_project\dist\vendor.js:37428:34)
at TemplateParser.module.exports.TemplateParser.parse (C:\dotnet_core_angular_project\dist\vendor.js:48548:19)
at JitCompiler.module.exports.JitCompiler._compileTemplate (C:\dotnet_core_angular_project\dist\vendor.js:62700:39)
at C:\dotnet_core_angular_project\dist\vendor.js:62620:62
at Set.forEach (native)
at JitCompiler.module.exports.JitCompiler._compileComponents (C:\dotnet_core_angular_project\dist\vendor.js:62620:19)
at C:\dotnet_core_angular_project\dist\vendor.js:62507:19
at Object.then (C:\dotnet_core_angular_project\dist\vendor.js:37417:92)
at JitCompiler.module.exports.JitCompiler._compileModuleAndComponents (C:\dotnet_core_angular_project\dist\vendor.js:62506:26)
at JitCompiler.module.exports.JitCompiler.compileModuleAsync (C:\dotnet_core_angular_project\dist\vendor.js:62435:37)
System.Exception: Call to Node module failed with error: Error: Template parse errors:
There is no directive with "exportAs" set to "ngModel" ("="button" class="btn btn-primary">Increment</button>
<input [(ngModel)]="name" [ERROR ->]#ctrl="ngModel" required>
<p>Value: {{ name }}</p>
"): ng:///AppModule/CounterComponent.html@8:30
Can't bind to 'ngModel' since it isn't a known property of 'input'. ("mentCounter()" type="button" class="btn btn-primary">Increment</button>
<input [ERROR ->][(ngModel)]="name" #ctrl="ngModel" required>
<p>Value: {{ name }}</p>
"): ng:///AppModule/CounterComponent.html@8:11
at syntaxError (C:\dotnet_core_angular_project\dist\vendor.js:37428:34)
at TemplateParser.module.exports.TemplateParser.parse (C:\dotnet_core_angular_project\dist\vendor.js:48548:19)
at JitCompiler.module.exports.JitCompiler._compileTemplate (C:\dotnet_core_angular_project\dist\vendor.js:62700:39)
at C:\dotnet_core_angular_project\dist\vendor.js:62620:62
at Set.forEach (native)
at JitCompiler.module.exports.JitCompiler._compileComponents (C:\dotnet_core_angular_project\dist\vendor.js:62620:19)
at C:\dotnet_core_angular_project\dist\vendor.js:62507:19
at Object.then (C:\dotnet_core_angular_project\dist\vendor.js:37417:92)
at JitCompiler.module.exports.JitCompiler._compileModuleAndComponents (C:\dotnet_core_angular_project\dist\vendor.js:62506:26)
at JitCompiler.module.exports.JitCompiler.compileModuleAsync (C:\dotnet_core_angular_project\dist\vendor.js:62435:37)
at Microsoft.AspNetCore.NodeServices.HostingModels.HttpNodeInstance.<InvokeExportAsync>d__7`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.NodeServices.HostingModels.OutOfProcessNodeInstance.<InvokeExportAsync>d__13`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
The full error output can be located in my repo which details reproduction steps.
I managed to get the ngModel directive working only when loaded via hot module replacement (doesn't work if you reload the page, so not a solution). The steps for reproducing this error (and getting the directive working via HMR) are detailed in this repository I made:
https://github.com/dougabugg/angular_dotnet_ngmodel_bug/tree/master
Have you checked to make sure that you import FormsModule in your app.module.server.ts file?
@uwbadgerdev importing FormsModule in app.module.server.ts fixed this issue (it was originally only in app.module.client.ts), but shouldn't that import have been there in the first place? Maybe the template should be updated?
Most helpful comment
@uwbadgerdev importing
FormsModuleinapp.module.server.tsfixed this issue (it was originally only inapp.module.client.ts), but shouldn't that import have been there in the first place? Maybe the template should be updated?