Can't bind to 'ngModel' since it isn't a known property of 'mat-select', BUT FormsModule is already imported

1.2k views Asked by At

I'm receiving the old and very well know error: "Can't bind to 'ngModel' since it isn't a known property of 'mat-select.'" BUT

FormsModule is imported on app.module.ts.

FormsModule is imported on the component in which I am using mat-select.

NgMaterialModule also is imported.

 <mat-select formControlName="threatType" [(ngModel)]="currentThreat">

currentThreat is a string.

Dozens of google answers show the same solution: imports ForsmModule. But as you can see, FormsModule is already imported.

For what other reason could this message be generated?

1

There are 1 answers

0
Gareth B On BEST ANSWER

Using the formControlName with ngModel is now deprecated. https://angular.io/api/forms/FormControlName#use-with-ngmodel-is-deprecated

If possible and not too much effort to redesign, use new formGroup with the formControls added, and all FormValidators in one.

A possible option I like, is to create a custom form for easy to convert back and two, if you want one form to be able to create or edit, based of data passed to a component. eg:

export class CustomForm extends FormGroup {

  constructor(myDto: IMyDto) {
    const myForm = new FormGroup({
          id: myDto ? new FormControl(myDto.id) : new FormControl('', [Validators.required]),
          active: myDto ? new FormControl(myDto.active) : new FormControl(false),
        }
    );
    super(myForm.controls);
  }

  public toDto(): IMyDto {
    return {
      id: this.value.id,
      active: this.value.active,
    };
  }
}

Then in my component

  myForm: CustomForm;
  myDto: IMyDto; -- init at some point or passed as @Input from a parent

  ngOnInit(): void {
    this.myForm = new CustomForm(this.myDto);
  }

and html

    <div [formGroup]="myForm">
        <input class=""
               id="formId"
               type="text"
               [required]="true"
               formControlName="id"/>
        <input class=""
               id="formActive"
               type="text"
               [required]="true"
               formControlName="active"
        />
      </div>