'Getting ERROR mat-form-field must contain a MatFormFieldControl

I am working on Angular form where I am trying to validate a reactive form . For template I am using Material design in my project ,

I am getting error on putting condition ngIf for validation in the textbox

error is -: ERROR Error: mat-form-field must contain a MatFormFieldControl.

Please see -:

To remove this issue I have already 1. imported MatInputModule in module.ts file 2. Already added You have to add matInput to input

But still getting same error

I am putting code below

template -:

<form class="example-form" novalidate (ngSubmit)='user_signup(user)'  [formGroup]='user'>

          <div class="row align-items-center">
            <div class="col-md-1">
              <label><img src="assets/imgs/mobile-icon.svg"/></label>
            </div>
            <div class="col-md-11">
              <mat-form-field class="example-full-width" >
                <input matInput type='number' placeholder="Phone Number:"  maxlength="10" name="phone" formControlName="phone" *ngIf="( user.get('phone').hasError('required') || user.get('phone').hasError('minlength') || user.get('phone').hasError('maxlength'))&& user.get('phone').touched" required/>
              </mat-form-field>
              <div>
              <div class="error" *ngIf="user.get('phone').hasError('required') && user.get('phone').touched">
                Phone number Required
              </div>
              <div class="error" *ngIf="user.get('phone').hasError('minlength') && user.get('phone').touched">
                Min 10 digit
              </div>
              <div class="error" *ngIf="user.get('phone').hasError('maxlength') && user.get('phone').touched">
                Max 10 digit
              </div>
              </div>

            </div>
          </div>
</form>

component.ts

 import { Component, OnInit } from '@angular/core';
    import { ServicesService } from '../service/services.service';
    import { FormGroup  , FormControl  , Validators } from '@angular/forms';
    @Component({
      selector: 'app-register',
      templateUrl: './register.component.html',
      styleUrls: ['./register.component.scss']
    })
    export class RegisterComponent implements OnInit {
     user: FormGroup;
 constructor( public restapi:ServicesService) {

        this.user = new FormGroup({
          password: new FormControl('', [Validators.required, Validators.minLength(6)]),
          email: new FormControl('', [Validators.required,Validators.email]),
          phone: new FormControl('', [Validators.required, Validators.minLength(10),Validators.maxLength(10)]),
          });

       }

  ngOnInit() {
  }
}

module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule, NO_ERRORS_SCHEMA } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { ComponentsComponent } from './components/components.component';
import { ReactiveFormsModule } from '@angular/forms';
import { HttpClientModule }    from '@angular/common/http';


import { MDBBootstrapModule, WavesModule, ButtonsModule, CardsFreeModule } from 'angular-bootstrap-md';
import { MatTabsModule, MatDialogModule } from '@angular/material';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { MatFormFieldModule} from '@angular/material';


/*angular material compoment*/
import { MatInputModule } from '@angular/material/input';
import {MatButtonModule} from '@angular/material/button';
import { RouterModule, Routes } from '@angular/router';
import {MatSlideToggleModule} from '@angular/material/slide-toggle';
import {MatTableModule} from '@angular/material/table';
import {MatSelectModule} from '@angular/material/select';
import {MatExpansionModule} from '@angular/material/expansion';
import {MatProgressSpinnerModule} from '@angular/material/progress-spinner';
import {MatSnackBarModule} from '@angular/material/snack-bar';
import {MatSliderModule} from '@angular/material/slider';
import {MatBadgeModule} from '@angular/material/badge';

/*component */
import { LoginComponent } from './login/login.component';
import { RegisterComponent } from './register/register.component';
import { FleshScreenComponent } from './flesh-screen/flesh-screen.component';


/* Service */
import { ServicesService } from './service/services.service';

@NgModule({
  declarations: [
    AppComponent,
    ComponentsComponent,
    LoginComponent,
    RegisterComponent,
    FleshScreenComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    BrowserAnimationsModule,
    MatInputModule,
    MatButtonModule,
    MDBBootstrapModule.forRoot(),
    ReactiveFormsModule ,
    HttpClientModule ,
    MatFormFieldModule

  ],
  schemas: [ NO_ERRORS_SCHEMA ],
  providers: [ServicesService],
  bootstrap: [AppComponent]
})
export class AppModule { }


Solution 1:[1]

When using a mat-form-field tag the inner input/ select tag, the tag must contain the matNativeControl attribute with it.

eg:

<mat-form-field>
    <input matInput matNativeControl placeholder="Input">
  </mat-form-field>

Refer official docs: Link

Solution 2:[2]

I have not tried it out, but you might be getting this error because of the *ngIf directive applied on the input element.

Why?

In particular, in this part of your code:

<mat-form-field>

    <input *ngIf="...">

</mat-form-field>

Angular interprets it as follows:

<mat-form-field>

    <ng-template [ngIf]="...">
      <input>
    </ng-template>

</mat-form-field>

So under the hood, the input element is not a direct content child of mat-form-field. No problem so far.

However, after digging a little bit into its source, MatFormField needs to find your input (with matInput directive applied) via @ContentChild. This means that you must supply your input element as a content child of mat-form-field.

In short, you need to place your input element directly under the mat-form-field element in some way.

Solution

Instead of applying *ngIf to the input element, apply it to mat-form-field, instead. That way, the input element is a content child of mat-form-field, as it should be.

<mat-form-field *ngIf="...">
    <input>
</mat-form-field>

Solution 3:[3]

It seems like there is a typo error please change your code to this

 <mat-form-field class="example-full-width" >
              <input matInput type='number' placeholder="Phone Number:"  maxlength="10" name="phone" formControlName="phone" *ngIf="user.get('phone').hasError('required') || user.get('phone').hasError('minlength') || user.get('phone').hasError('maxlength') && user.get('phone').touched" required/>
            </mat-form-field>

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Glin Zachariah
Solution 2
Solution 3