7

I have a form like this:

<form id="save_form" (ngSubmit)="save()">
    <input id="input_user" type="text" [formControl]="myForm" />
    <button type="submit">save</button>
</form>

I have a test like this:

const inputUser: HTMLInputElement = fixture.nativeElement.querySelector("#input_user");
const saveForm: DebugElement = fixture.debugElement.query(By.css("#save_form"));

inputUser.value = "Bob";
//component.myForm.setValue("Bob");

saveForm.triggerEventHandler("ngSubmit", null);

fixture.detectChanges();

In my component, the input value is not updating myForm. If I use the commented out syntax, the form is updated, but the input tag is not populated.

I am trying to simulate an input value from a user, is the formcontrol supposed to be updated through the input value in a test? I feel like if I just updated the formcontrol manually I am not simulating a user.

UPDATE:

    //component.searchUsers.setValue("Bob");
    const e: Event = document.createEvent("Event");
    e.initEvent("input", false, false);
    inputUser.value = "Bob";
    inputUser.dispatchEvent(e);
    fixture.detectChanges();

    myForm.triggerEventHandler("ngSubmit", null);
    fixture.detectChanges();
    fixture.whenStable().then(() => 
    expect(condition).toBe(true));

1 Answers1

5

You need to trigger change detection by dispatching a change event from the input, then detect changes. I do it as follows.

const e:Event = document.createEvent('Event');
e.initEvent('input', false, false);
inputUser.value = 'Bob';
inputUser.dispatchEvent(e);
fixture.detectChanges();
fixture.whenStable().then(() => expect(something).toEqual('something'));
The Head Rush
  • 3,157
  • 2
  • 25
  • 45
  • so after I set input.value to "Bob", and before I triggered ngSubmit, I added those lines, but no luck. It makes sense, but that didn't seem to work. Was that what you meant? – Daniel Plainview May 08 '18 at 16:17
  • Sorry, for being unclear. Set the value in the ``, not the `FormControl`. See updated answer. – The Head Rush May 08 '18 at 16:23
  • Updated from a test that passes for me using `@angular 5.0.2`, `karma ^1.7.1`, & `jasmine ~2.5.2`. – The Head Rush May 08 '18 at 16:37
  • Sorry thats gross looking, then in my component after submit: `this.myForm.value` comes out as null right away, and untouched – Daniel Plainview May 08 '18 at 16:57
  • Put the expectation in a `whenStable` block. There's a couple rounds of change detection that have to happen. – The Head Rush May 08 '18 at 17:24
  • I updated my code above, still the same issue. Your answer seems like it should work :( – Daniel Plainview May 08 '18 at 18:26
  • I'm wondering if the problem might be the call to `triggerEventHandler`. I call the submit method directly in my functioning tests. See the accepted answer: https://stackoverflow.com/questions/47753863/triggereventhandler-in-unit-testing-angular-4 – The Head Rush May 08 '18 at 19:20
  • I messed around a little more and wasn't able to get it to work. I appreciate your time on this, I'll check back on this thread later but for now I'm going to stick with setting the input field from the formcontrol layer (inputUser.setValue()). It seems to work flawlessly outside not 100% simulating a user. Thanks agian – Daniel Plainview May 08 '18 at 19:56