4

When I try to use the disable method on a formGroup in my Angular 6 app , I get this error in the browser console :

TypeError: this.personForm.disable is not a function

Although the method is mentioned in the documentation & it is even suggested by VS Code as in this snapshot.Even VS Code is suggesting the method

My code is here:

// ... many parts skipped, the form here is template driven 
// but still personForm is a FormGroup , 
// I am trying to disable the whole FormGroup with all child elements
@ViewChild('personForm') personForm: FormGroup;

        if (true) {
       // if I console.log here the form, I can see it is created already
         console.log(this.personForm);              
// output of console.log is 
// NgForm {submitted: false, _directives: Array(0), ngSubmit: EventEmitter, form: FormGroup}

         this.personForm.disable();
        }

What is the problem here ?

UPDATE 1:

I have created a stackblitz to show the issue

here is the link for that demo

UPDATE 2: As the error is not shown on initial loading, if you remove the this.firstStepForm.disable(); & rewrite it , you will get the error, but anyway the behavior is not correct, the form field is not disabled as expected

Also, refreshing the browser part in the stackblitz will show an error snackbar

Ahmed Elkoussy
  • 8,162
  • 10
  • 60
  • 85

2 Answers2

6

The form object that you have created using template driven approach is of type NgForm and not FormGroup

There is a form attribute inside ngForm object which is actually of type FormGroup.

So you should be doing

this.personForm.form.disable()

EDIT :

You have to move your code to AfterViewChecked life cycle hook event, since your formGroup wont be ready ngAfterViewChecked() is triggered.

ngAfterViewChecked() {
      console.log(this.personForm.form);    
      this.personForm.form.disable(); 
      this.cdr.detectChanges();  
} 

And also postpone the change detection to avoid expression changed error using ChangeDetectorRef.

DEMO

Amit Chigadani
  • 28,482
  • 13
  • 80
  • 98
  • Thanks for your answer, actually it is a FormGroup , you can see the type in my code , the way you are using here is for the reactive FormGroup, mine is template driven FormGroup. I have added stackblitz example to better show the issue – Ahmed Elkoussy Jul 03 '18 at 17:42
  • But I do not see any errors in your stackblitz as you have mentioned. – Amit Chigadani Jul 03 '18 at 17:45
  • Yeah, sure thing, strangely it is not giving errors but still not disabling the form, I have tested locally & in stackblitz https://stackblitz.com/edit/angular-nf9jog?file=app/app.component.ts – Ahmed Elkoussy Jul 03 '18 at 18:42
  • 1
    Move your code to `AfterViewChecked` lifecycle hook and also postpone the change detection to avoid expression changed error. – Amit Chigadani Jul 03 '18 at 18:56
  • 1
    Great solution , thanks for your very useful help , I am a bit afraid of these hooks as they seem a little bit too much but it works , thank you – Ahmed Elkoussy Jul 03 '18 at 19:25
  • With pleasure :) , I would appreciate it if you upvote my answer too to get it seen as well , it will help starters to be careful when relying on editor suggestions – Ahmed Elkoussy Jul 03 '18 at 19:30
1

I have discovered the reason for this error:

This form is made in the html template using ngForm, then I used ViewChild to get hold of the form in the typescript file, I noticed that I made that object of type FormGroup but ngForm is different than FormGroup (in my use cases it wasn't clear) that is why the FormGroup disable method is not working on the ngForm

Note:

(VS code is suggesting it as my type for that variable is FormGroup which is misleading the editor to give me that suggestion)

Thanks for everyone who tried to help.

Update:

In case someone is reluctant to depend on detectChanges() like me & Building upon the excellent Answer of Amit , we can disable the NgForm in this AfterContentChecked to avoid using detectChanges()

  // instead of disabling here & using cdr.detectChanges()

  // ngAfterViewChecked() {
  //     console.log(this.personForm.form);    
  //     this.personForm.form.disable(); 
  //     this.cdr.detectChanges();  
  // } 

  // we can put our disable here
  ngAfterContentChecked() {
    this.personForm.form.disable();
  }

Stackblitz demo

Ahmed Elkoussy
  • 8,162
  • 10
  • 60
  • 85