angularangular-template-form

Listen for template driven form changes in Angular 10


I have a template driven form in my angular 10 app that I am trying to listen for changes to so that I can show an 'changed, please submit updates' message to the user.

HTML

<form (ngSubmit)="submit()" class="form-horizontal" #opportunityForm="ngForm">
...

opportunity.component.ts

export class OpportunityComponent implements OnInit {

  @ViewChild('opportunityForm') ngForm: NgForm;

  ngOnInit(): void {
    ...
    this.formChangesSubscription = this.ngForm.form.valueChanges.subscribe(x => {
      console.log(x);
    })

but it get an error that:

TypeError: Cannot read property 'form' of undefined

because the ngForm is not initialised. This is a similar question to: how to listen of angular template driven form changes which has a running answer at https://ng-run.com/edit/CGoUiw88N7OmI7x0YmHJ which has the same problem.

How can I grab the form and make sure it exists before I listen for changes? I am using Angular 10.2.0

Not sure if this makes a difference but the whole page is wrapped in a

<div *ngIf="loaded">

which is set after an api call in the ngOnInit

ngOnInit(): void {
  this.dataService.getOpportunity(this.id)
        .subscribe(data => {
           ...  //fills the data up
        }, error => console.error(error),
        () => {
            console.log(this.loaded);
            console.log(this.ngForm);
        });

puts out true (for loaded) and undefined (for this.ngForm).

UPDATE*

So it does look like it's because I have the entire form only loaded after the data comes bac. Because it's not on the page then @ViewChild can hook onto it. I put my *ngIf on a div inside the form and it is working fine


Solution

  • Try adding static: true option to @ViewChild decorator:

    @ViewChild('opportunityForm', { static: true }) ngForm: NgForm;
    

    Ng-run Example

    otherwise you have to move subscription to ngAfterViewInit hook