23

i'm trying to create custom angular 2 validator directive, which inject NgControl like this :

@Directive({
  selector: '[ngModel][customValidator]',
  providers: [{provide: NG_VALIDATORS, useExisting: CustomValidatorDirective, multi: true}]
})
export class CustomValidatorDirective implements Validator {
  private validateFunction: ValidatorFn;

  constructor(private control: NgControl) { };

}

But i get the following error:

Cannot instantiate cyclic dependency! NgControl

Does anyone know how i can workarround it, so i can access the ngControl after intialization?

Krasimir Kirilov
  • 485
  • 2
  • 5
  • 14

2 Answers2

24

You can inject NgControl via Injector to avoid cyclic dependency.

constructor(private _injector: Injector) { }

ngOnInit() {
  console.log(this._injector.get(NgControl))
}
Bladito
  • 1,079
  • 11
  • 10
  • 5
    It seems that `injector.get(NgControl)` is depreciated. See [this](https://stackoverflow.com/a/56061527/1730846) for an alternative solution. – Mojtaba Aug 18 '19 at 10:24
5

Providers, Pipes, Directives declaration are removed from @Component or @Directive decorators after RC6 or RC7. So you just need to remove

providers: [{provide: NG_VALIDATORS, useExisting: CustomValidatorDirective, multi: true}] 

from directive

and add it into @NgModule({}) decorator

@NgModule({
 ...
 providers: [{provide: NG_VALIDATORS, useExisting: CustomValidatorDirective, multi: true}]

})
micronyks
  • 54,797
  • 15
  • 112
  • 146
  • 5
    AFAIK `providers` property on a directive still works. It was not removed https://github.com/angular/angular/blob/master/modules/%40angular/core/src/metadata/directives.ts#L337 https://angular.io/docs/ts/latest/cookbook/ngmodule-faq.html#!#q-component-or-module – yurzui Oct 01 '16 at 19:29
  • @yurzui Thanks for the share. Then problem could be not to provide such provider configuration here. Or may be providing providers here may create other instance or something. – micronyks Oct 01 '16 at 19:36
  • 2
    I think putting the provider registration in the NgModule rather than the Directive will cause the validator to be shared across the modules which can access the CustomValidatorDirective. Obviously it will pollute NG_VALIDATORS when other directives also use it. – e-cloud Mar 03 '17 at 11:26