0

i am trying to pass ngModel in child component to displaying error from common component.

It giving error like. Template parse errors:No provider for NgControl.

can any one please check the code and let me know what i am missing.

Plunker

Parent component

      <div>
  <h2>Hello {{name}}</h2>
  <form #countryForm="ngForm">
    <div class="form-group row">
      <label for="txtCountryName" class="col-sm-3 col-form-label">Country Name</label>
      <div class="col-sm-9">
        <input type="text" [(ngModel)]="name" ngModel #countryName="ngModel" name="name" class="form-control" id="txtCountryName" placeholder="Country Name"              required minlength="5" maxlength="15">
        <app-error-message [formControl]="countryName"></app-error-message>
      </div>
    </div>
  </form>
</div>

Child component

@Component({
selector: 'app-error-message',
template: `<ng-container *ngIf="formControl">
            <div [hidden]="(formControl.valid || formControl.pristine) && (formControl.errors == null || formControl.errors.invalid == null)" class="alert alert-danger">  
              {{GetValidationMessage()}} 
            </div> 
          </ng-container>`

  })

export class ErrorMessageComponent  {
@Input() public formControl: any = null;

public GetValidationMessage() {
    let errorMessage: string = "";
    if (this.formControl.errors) {
        if (this.formControl.dirty || this.formControl.touched) {
            if (this.formControl.errors.required != null) {
                errorMessage = "This field is required.";
            }
            if (this.formControl.errors.minlength != null) {
                errorMessage += "This field must be 8 characters long, we need another " + (this.formControl.errors.minlength.requiredLength - this.formControl.errors.minlength.actualLength) + " characters";
            }
        }
        if (this.formControl.errors.invalid != null) {
            errorMessage += this.formControl.errors.errorMessage;
        }
    }
    return errorMessage;
}

}

Dhaval kansagara
  • 551
  • 4
  • 17
  • is data being passed to `formControl` in your child component? – SONGSTER Dec 08 '17 at 20:06
  • Possible duplicate of [angular2 pass ngModel to a child component](https://stackoverflow.com/questions/41350584/angular2-pass-ngmodel-to-a-child-component) – Hugo Noro Dec 08 '17 at 20:18

2 Answers2

2

You should use another name for @Input to not intersect with built-in directive NgControlStatus that requires NgControl provider https://github.com/angular/angular/blob/3ce3b4d2afdc5198a9a5a9432db1f88e2e5d1972/packages/forms/src/directives/ng_control_status.ts#L56

To do so you can either completely replace property name

error-message.component.ts

@Input() public control: any = null;

parent.html

<app-error-message [control]="countryName"></app-error-message>

Forked Plunker

or use alias for @Input

error-message.component.ts

@Input('control') public formControl: any = null;

parent.html

<app-error-message [control]="countryName"></app-error-message>

Forked Plunker

yurzui
  • 205,937
  • 32
  • 433
  • 399
1

try accessing the local template reference variable #countryName, in the parent component. through @ViewChild

Then set a property public countryName: any equal to the local template variable.

//Parent Component

export class ParentComp implements AfterViewInIt{
      @ViewChild('add_template_reference_variable_here') countryNameRef;
      public countryName: any;

      ngAfterViewInit(): void {
       this.countryName = this.countryNameRef;
      }
}

And then bind new variable to [formControl]="countryName"

// Parent Html Template

<app-error-message [formControl]="countryName"></app-error-message>
SONGSTER
  • 585
  • 3
  • 11
  • 28