[Error] ngModel with formControl in Angular

Table of Contents

Error Description

The error “It looks like you’re using ngModel on the same form field as formControl” typically occurs when Angular developers attempt to use both template-driven and reactive forms directives on the same input element. Specifically, this happens when you bind a form control in a reactive form with the formControl directive and also try to use the [(ngModel)] two-way data binding directive.

Reason: Root Cause of the Error

In Angular, reactive and template-driven forms are two distinct approaches to handling form inputs. The reactive forms approach provides more explicit control over forms through a model-driven approach, whereas template-driven forms allow for easier, two-way data binding using the ngModel directive.

The error arises because mixing these two approaches on the same element is deprecated and is not a supported practice in Angular—mainly to prevent confusion and to ensure a clear and consistent data flow within the form.

Resolving the Error

To resolve the error, decide on one approach to use for your form (either reactive or template-driven) and apply it consistently.

Using Reactive Forms Approach

To switch to a purely reactive forms approach, follow these steps:

  1. Remove [(ngModel)] from your input element.
  2. Keep the formControl or formControlName directive intact.
  3. Ensure that your form control is initialized in your component class. For instance:
    this.myForm = this.formBuilder.group({
        myControl: ['', Validators.required] // Initialize form control
    });
  4. Update the component to respond to value changes with this.myForm.get('myControl').valueChanges.
  5. Replace any use of ngModel in the component with the form control’s value.
import { Component } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';

@Component({
  selector: 'app-example',
  template: `
    <form [formGroup]="myForm">
      <input formControlName="myControl">
    </form>
  `
})
export class AppExampleComponent {
  myForm: FormGroup;

  constructor(private formBuilder: FormBuilder) {
    this.myForm = this.formBuilder.group({
      myControl: ['', Validators.required]
    });

    // Subscribe to value changes
    this.myForm.get('myControl').valueChanges.subscribe(newValue => {
      console.log('New value:', newValue);
      // You can perform additional actions here based on the new value
    });
  }
}

References:

Conclusion

Following the guide above, you should successfully resolve the “ngModel on the same form field as formControl” error by committing to either reactive or template-driven forms. Adhering to one approach helps maintain clarity in the form-handling strategy and prevents unexpected behaviors in Angular applications.