Angular 4 - The "ngForm" directive is missing the "exportAs" setting and cannot be found

I've encountered various responses to this issue on stackoverflow regarding the configuration of the app. However, despite being confident in the correctness of my configuration as the app runs smoothly, my Karma test fails inexplicably.

Below is my app.module.ts:

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 { }

The details of the login-form.component.ts file are presented below:

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 =>
        this.managerService.start(oauth).subscribe(
                  res => console.log(res),
                  (error: HttpErrorResponse) => this.processError(error)
                )
      );
  }

Check out the login-form.component.html code snippet below:

<form (ngSubmit)="onSubmit()" #loginForm="ngForm" class="form-signin">

    <div class="form-group">
        <input type="text" class="form-control" id="username" placeholder="Username" [(ngModel)]="login.username" name="username" required>
    </div>
    <div class="form-group">
        <input type="password" class="form-control" id="password" placeholder="Password" [(ngModel)]="login.password" name="password" required >
    </div>

    <button type=submit class="btn btn-lg btn-primary btn-block" [disabled]="!loginForm.form.valid">Sign In</button>
    <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
</form>

A brief overview of the unit test is provided below:

import { async, ComponentFixture, TestBed } from '@angular/core/testing';

import { LoginFormComponent } from './login-form.component';

describe('LoginFormComponent', () => {
  let component: LoginFormComponent;
  let fixture: ComponentFixture<LoginFormComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ LoginFormComponent ]
    })
    .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(LoginFormComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should be created', () => {
    expect(component).toBeTruthy();
  });
});

Moreover, here's an outline of my package.json for holistic insight:

{
  "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"
  }
}

In connection with

There is no directive with "exportAs" set to "ngForm"
, I'm also facing the issue of
Can't bind to 'ngModel' since it isn't a known property of 'input'
with regards to both input fields.

Despite adhering to the guidelines outlined here, I am baffled by the predicament at hand. My components solely consist of login and app, supplemented by Manager Service as the only service, while the rest of my code comprises plain classes.

Answer №1

In order to properly test your module, it's important to include the FormsModule.

When setting up your testing configuration with TestBed, make sure to add this line:
TestBed.configureTestingModule({
  declarations: [ LoginFormComponent ],
  imports: [ FormsModule ]
})
.compileComponents();

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Compiling Typescript with union types containing singleton types results in errors

I'm having trouble understanding why the code below won't compile: type X = { id: "primary" inverted?: boolean } | { id: "secondary" inverted?: boolean } | { id: "tertiary" inverted?: false } const a = true const x: X = { id: a ? ...

Utilizing proxies and leveraging the power of the Map collection in tandem

I have been exploring the Map collection and came across the [[MapData]] internal slot, which led me to utilize Reflect for trapping purposes. After some trial and error, I came up with the following code snippet: const map = new Map(); const proxiedMap ...

Dealing with data returned by GraphQL API using axios

My current method for making the desired post request looks like this: async function fetchMediaList(): Promise<MediaListCollection> { let result = {} as MediaListCollection; await axios .post<MediaListCollection>( "https:// ...

What is the best way to add a clickable link/button in Angular 8 that opens a webpage in a new tab?

I'm looking to create a website that opens in a new tab when a link or button is clicked. I'm unsure how to achieve this in Angular 8. ...

Prevent selection of items in ng-select. Modifying the default item selection behavior in ng-select

In my code, I am utilizing an angular-multiselect component to upload a list of items and populate the [data] variable of the angular-multiselect. This component displays the list of data with checkboxes, allowing me to select all, search, and perform vari ...

What is the best way to add all IDs to an array, except for the very first one

Is there a way to push all response IDs into the idList array, excluding the first ID? Currently, the code below pushes all IDs to the list. How can it be modified to exclude the first ID? const getAllId = async () => { let res = await axios({ m ...

Angular 8 and Bootstrap 4 Integration: Navbar Functionality Working, but Issue with Auto-Closing on Click Action (Both Inside and Outside Navbar)

While using ng-bootstrap with Angular 8, I encountered a problem with the navbar. The navbar functions properly by being responsive and opening/closing when clicking the hamburger icon. However, the issue arises when it does not automatically close when a ...

Switching Angular-cli from scss to css

I accidentally created my Angular project using scss style, but I want to switch to css style. Is there a way to convert scss style to css using Angular-cli? ...

How can you dynamically display options in ngx-contextmenu based on certain conditions?

I successfully integrated a context menu into my Angular 6 project using the ngx-contextmenu library. I would like to display certain options in this menu only if the selected object has a specific attribute defined. In the provided example, how can I make ...

Setting a Validator for a custom form control in Angular: A step-by-step guide

I need to apply validators to a specific control in formGroup from outside of a custom control component: <form [formGroup]="fg"> <custom-control formControlName="custom"> </custom-control> </form> this. ...

Typescript: The .ts file does not recognize the definition of XMLHttpRequest

I have encountered an issue with a .ts file containing the following code: var xhttp = new XMLHttpRequest(); After running the grunt task to compile the ts files using typescript, no errors were reported. However, when I attempt to instantiate the class ...

Explore the ngx-swiper-wrapper with stunning effects like Cube, Coverflow, and Flip!

I'm currently using ngx-swiper-wrapper and I haven't been able to locate the Cube, Coverflow, and Flip effects that are available in the original Swiper plugin. Has anyone come across these effects? Are they included in ngx-swipper-wrapper? ngx- ...

What is the proper way to define the scope for invoking the Google People API using JavaScript?

I am attempting to display a list of directory people from my Google account. export class People { private auth: Auth.OAuth2Client; private initialized: boolean = false; private accessToken: string; constructor(private readonly clientEmail: strin ...

Accessing properties through recursive type aliases

I am attempting to transcribe this class originally written in JavaScript. Here is the code snippet provided. type SchemaDefinition<Schema> = {[Key in keyof Schema]: Schema[Key][] | {[K in keyof Schema[Key]]: SchemaDefinition<Schema[Key][K]>}} ...

Is there a way I can replace this for loop with the array.some function?

I am looking to update the filterOutEmails function in the following class to use array.some instead of the current code. export class UsertableComponent { dataSource: MatTableDataSource<TrialUser> createTableFromServer = (data: TrialUsers[], ...

Managing plain text and server responses in Angular 2: What you need to know

What is the best way to handle a plain text server response in Angular 2? Currently, I have this implementation: this.http.get('lib/respApiTest.res') .subscribe(testReadme => this.testReadme = testReadme); The content of lib/respApi ...

Managing several instances of NgbPagination on a single webpage

I am facing a challenge with having multiple NgbPagination components on a single page. For more information, please visit: Initially, I attempted to use ids but encountered an issue where changing one value in the first pagination affected both tables. ...

Don't forget to include the line 'import "reflect-metadata"' at the beginning of your entry point for Jest tests

As I work on developing an application using dependency injection with tsyringe, I came across a case where a service receives the repository as a dependency. Here is an example: import { injectable, inject } from 'tsyringe' import IAuthorsRepos ...

What steps can be taken to fix error TS2731 within this code snippet?

I've been working through a book and encountered an issue with the code below. // This code defines a function called printProperty that has two generic type parameters function printProperty<T, K extends keyof T> (object: T, key: K) { let pro ...

How to pass parameters from a directive to a child component in Angular

I am currently attempting to create a child component that can pass parameters using a directive, but I have not been able to find any tutorials on how to achieve this yet. I have tried looking at some resources, such as this one on Stack Overflow: Get re ...