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?
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With