pax
pax

Reputation: 1903

Angular: directive on custom formControl results in error

When I add my custom idNumber directive on to the child HTML element, all works fine. I would like to use it in the parent class. That however doesn't work.

// custom directive ////////
@Directive({
selector: "[idNumber]"
})
export class IcoDirective implements OnInit {
formControl: FormControl;
constructor(private control: NgControl) { }

ngOnInit() {
    this.formControl = <FormControl>this.control.control;
    this.addValidators(this.formControl);
}

addValidators(formControl: FormControl) {
    formControl.setValidators(Validators.compose(
            [... some validators...]
        ));
    }


// child HTML ////////
<mat-form-field>
    <input matInput idNumber // if I put the directive here, all works fine.
    [formControl]="idNumberFormControl"
</mat-form-field>

// child TS ////////
ngOnInit() {
    this.idFormControl = new FormControl();
    this.idFormControl.valueChanges.subscribe(value => {
    this.manageUserInput(this.idFormControl );
    });
}

insertIntoForm(parentFormGroup: FormGroup): void {
    parentFormGroup.addControl(this.name, this.idFormControl );
}


// parent HTML ////////
<custom-input-string
    idNumber // if I put the directive here (not in child), I get an error.
    [name]="'idNumber'">
</custom-input-string>

// parent TS ////////
@ViewChild(CustomInputStringComponent) child: CustomInputStringComponent;

ngAfterViewInit() {
    setTimeout(() => {
        this.child.insertIntoForm(this.signupForm);
    }, 0);
}


The error I get:


ERROR Error: Uncaught (in promise): Error: StaticInjectorError(AppModule)
[MatInput -> NgControl]:
StaticInjectorError(Platform: core)[MatInput -> NgControl]:

NullInjectorError: No provider for NgControl!
Error: StaticInjectorError(AppModule)[MatInput -> NgControl]:
StaticInjectorError(Platform: core)[MatInput -> NgControl]:

NullInjectorError: No provider for NgControl!

I know it has something to do with the dependency injection, and I tried to look for a solution all over the internet. Unsuccessfully so far.
Thank you all for your help.

Upvotes: 2

Views: 1529

Answers (1)

user4676340
user4676340

Reputation:

That's because you're not on the input anymore.

You have to use ContentChild to get the component you want, then use the control of the said component.

Stackblitz (based on your previous question)

@ContentChild(CustomComponentComponent) component: CustomComponentComponent;

constructor(
) { }

ngAfterViewInit() {
  this.component && this.component.control.setValidators([Validators.required]);
}

Upvotes: 2

Related Questions