question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

A text input in a form does not update ngModel in tests

See original GitHub issue

I’m submitting a…


[x] Bug report  

Current behavior

I test a component containing a form element and a text input element in it. There is a two-way binding between the input element and a text property of a component class via ngModel directive.

The test updates the input’s value, fires dispatchEvent and checks the property of the component. The test fails:


Error: Expected 'Default title' to equal 'Updated Task'.
    at stack (http://localhost:9876/base/node_modules/jasmine-core/lib/jasmine-core/jasmine.js?73bc53d3671677e6a093fc74e4f9bcde57e5f7ad:2338:17)
    at buildExpectationResult (http://localhost:9876/base/node_modules/jasmine-core/lib/jasmine-core/jasmine.js?73bc53d3671677e6a093fc74e4f9bcde57e5f7ad:2308:14)
    at Spec.expectationResultFactory (http://localhost:9876/base/node_modules/jasmine-core/lib/jasmine-core/jasmine.js?73bc53d3671677e6a093fc74e4f9bcde57e5f7ad:858:18)
    at Spec.addExpectationResult (http://localhost:9876/base/node_modules/jasmine-core/lib/jasmine-core/jasmine.js?73bc53d3671677e6a093fc74e4f9bcde57e5f7ad:487:34)
    at Expectation.addExpectationResult (http://localhost:9876/base/node_modules/jasmine-core/lib/jasmine-core/jasmine.js?73bc53d3671677e6a093fc74e4f9bcde57e5f7ad:802:21)
    at Expectation.toEqual (http://localhost:9876/base/node_modules/jasmine-core/lib/jasmine-core/jasmine.js?73bc53d3671677e6a093fc74e4f9bcde57e5f7ad:2252:12)
    at http://localhost:9876/_karma_webpack_/webpack:/src/app/app.component.spec.ts:35:26
    at ZoneDelegate.webpackJsonp../node_modules/zone.js/dist/zone.js.ZoneDelegate.invoke (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:388:1)
    at AsyncTestZoneSpec.webpackJsonp../node_modules/zone.js/dist/zone-testing.js.AsyncTestZoneSpec.onInvoke (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone-testing.js:479:1)
    at ProxyZoneSpec.webpackJsonp../node_modules/zone.js/dist/zone-testing.js.ProxyZoneSpec.onInvoke (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone-testing.js:236:1)

NOTE: If I comment out the form element in the app.component.html then the test passes.

Expected behavior

Chrome 64.0.3282 (Windows 7.0.0): Executed 1 of 1 SUCCESS

Minimal reproduction of the problem with instructions

1. Create project:

ng new angular-app

2. Update files:

app.component.html - replace all the text with the following:

<form novalidate (ngSubmit)="onSubmit()">
  <input name="title" type="text" [(ngModel)]="title">
</form>

app.component.ts - replace all the text with the following:

import {Component} from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'Default title';

  onSubmit() {
    console.log('title is:' + this.title);
  }
}

app.component.spec.ts - replace all the text with the following:

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

import {AppComponent} from './app.component';
import {By} from "@angular/platform-browser";

describe('AppComponent', () => {
  let fixture: ComponentFixture<AppComponent>;
  let comp: AppComponent;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [
        AppComponent
      ],
      imports: [FormsModule],
    }).compileComponents().then(() => {
      fixture = TestBed.createComponent(AppComponent);
      comp = fixture.debugElement.componentInstance;
    })
  }));

  it('should bind an input to a property (async)', async(() => {
    fixture.detectChanges();

    // Update the title input
    const inputElement = fixture.debugElement.query(By.css('input[name="title"]')).nativeElement;
    inputElement.value = 'Updated Task';
    inputElement.dispatchEvent(new Event('input'));

    fixture.whenStable().then(() => {
      fixture.detectChanges();
      expect(comp.title).toEqual('Updated Task');
    });
  }));
});

app.module.ts - replace all the text with the following:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';

import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    FormsModule
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

What is the motivation / use case for changing the behavior?

I need to test a component with a form inside.

3. Run tests:

ng test

Environment


Angular CLI: 1.7.2
Node: 8.5.0
OS: win32 x64
Angular: 5.2.7
... animations, common, compiler, compiler-cli, core, forms
... http, language-service, platform-browser
... platform-browser-dynamic, router

@angular/cli: 1.7.2
@angular-devkit/build-optimizer: 0.3.2
@angular-devkit/core: 0.3.2
@angular-devkit/schematics: 0.3.2
@ngtools/json-schema: 1.2.0
@ngtools/webpack: 1.10.1
@schematics/angular: 0.3.2
@schematics/package-update: 0.3.2
typescript: 2.5.3
webpack: 3.11.0

Browser:
- [*] Chrome (desktop) version XX

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Reactions:4
  • Comments:5 (1 by maintainers)

github_iconTop GitHub Comments

3reactions
karacommented, Mar 29, 2018

This looks like a duplicate of https://github.com/angular/angular/issues/22606.

0reactions
angular-automatic-lock-bot[bot]commented, Sep 14, 2019

This issue has been automatically locked due to inactivity. Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Angular 2 - [(ngModel)] not updating after [value] changes
I updated the second example my answer. Try adding a ngModel exportAs attribute statement and removing the template reference variable. This is assuming...
Read more >
NgForm - Angular
Returns whether the form submission has been triggered. ... native HTML5 validation, add the ngNoForm and the <form> tags won't create an NgForm...
Read more >
Difference between (change) and (ngModelChange) in Angular
Really, it comes down to using ngModel or not. If you're using [(ngModel)] then you don't need to worry about this, otherwise use...
Read more >
Angular Forms Guide: Template Driven and Reactive Forms
Forms built with this directive could only be tested in an end to end ... ngModel and other form-related directives are not available...
Read more >
AngularJS: Developer Guide: Forms
The value of ngModel won't be set unless it passes validation for the input field. For example: inputs of type email must have...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found