Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test template driven forms in angular 6

I have a template driven form:

<form #form="ngForm" (ngSubmit)="onSubmit()">
      <input class="form-control input-lg" id="venue_name" name="venue_name" type="text" #venue_name="ngModel"
             [(ngModel)]="tournament.venue.venue_name" required>
      <input id="address" name="address" placeholder="search for location" required #address="ngModel"
             type="text" class="form-control input-lg" #search [(ngModel)]="tournament.venue.address">
</form>

In my component, I have:

@ViewChild(NgForm) ngForm: NgForm;

In my test, I have:

fixture = TestBed.createComponent(TournamentEditVenueComponent);
comp = fixture.componentInstance;
form = comp.ngForm.form;
console.log(form);

Here I can see in Chrome console:

FormGroup {venue_name: FormControl, address: FormControl, details: FormControl, country_id: FormControl}

So the form seems to be reachable

but when I try to reach it with

    console.log(form.controls);

or

    console.log(form.controls['venue_name']);

the first one is empty and the second one is undefined.

Why ? How should I do?

like image 281
Juliatzin Avatar asked Jul 06 '18 11:07

Juliatzin


People also ask

Is unit testing is applicable only for template driven forms?

With template-driven forms the state is in the view and unless the component has a reference to the template form with a ViewChild decorator there is no way to test the form using a unit test.

What are the two parts of template driven Angular forms?

Angular supports two design approaches for interactive forms. You can build forms by using Angular template syntax and directives to write templates with the form-specific directives. This tutorial describes the directives and techniques to use when writing templates.


Video Answer


1 Answers

Unsure of the exact reasoning for this - Would need to look into how the fixture works more, but the below code worked for me.

For a solution it seems that you don't call fixture.detectChanges() once you've done the setup and this is required in your test to set up the data bindings. More info: https://angular.io/guide/testing

Once this is done based on this answer Trying to unit test template-based form in a component, form has no controls it explains that they fixed it by then also ensuring that the fixture is stable -

fixture.whenStable() returns a promise that resolves when the JavaScript engine's task queue becomes empty.

If you try and access the form controls within here then it will work as in the example below.

fixture = TestBed.createComponent(TournamentEditVenueComponent);
comp = fixture.componentInstance;
fixture.detectChanges();

fixture.whenStable().then( () => {
   console.log(comp.ngForm.controls['venue_name'])
   component.ngForm.controls['venue_name].setValue('test_venue');
})

Hope this helps.

like image 90
Buttonsz Avatar answered Sep 24 '22 03:09

Buttonsz