1

So i was looking at the angular core files, I'm a bit confused on how these four pieces of code connect?

  1. Code for injection token which is a class
    export class InjectionToken extends OpaqueToken {
          private _differentiate_from_OpaqueToken_structurally: any;
          constructor(desc: string) { super(desc); }

          toString(): string { return `InjectionToken ${this._desc}`; }
    }

  1. Code for NG_VALIDATORS which uses the injection token
    export const NG_VALIDATORS = new InjectionToken>('NgValidators');

  1. Required validator which uses the NG_VALIDATORS
    export const REQUIRED_VALIDATOR: Provider = {   
        provide: NG_VALIDATORS,   
        useExisting: forwardRef(() => RequiredValidator),   
        multi: true 
    };

    @Directive({
        ...
    }) export class RequiredValidator implements Validator {
        //Code here
    }

I am having problem tracing back the code from the declaration of REQUIRED_VALIDATOR to injection token. I understand about most of the basic elements but not sure how the "useExisting" is being used for RequiredValidator class (i understand forwardRef). And how NG_VALIDATORS gets benefited, which itself being a constant by definition

6
  • dependency injection is one key concept of Angular, see this documentation. Even as it is almost easy to use, the code behind it is quite complex . Commented Aug 8, 2017 at 2:06
  • hey, did my answer help you? Commented Aug 9, 2017 at 7:42
  • I'm still confused on the fact regarding NG_VALIDATORS, as i was reading on multi providers blog.thoughtram.io/angular2/2015/11/23/… It talks about NG_VALIDATORS being a container for all built in validators plus any custom ones we declare. Your answer talks about redirection of request from one token to another. Although i understand the core concept but i'm just researching on the core angular code for how NG_VALIDATORS gets initialized and attached on the form itself Commented Aug 9, 2017 at 9:06
  • okay, take your time. the articles on thoughtram are not very deep, they often represent the internals in the overly simplistic way. NG_VALIDATORS being a container for all built in validators - this is not true because otherwise you would have all validators added elsewhere for the input on particular form Commented Aug 11, 2017 at 11:13
  • I'm not sure but if i have the concept up at graps, but please excuse if i misused the word container that's what i'm linking to, although which might be wrong Commented Aug 11, 2017 at 11:43

1 Answer 1

4

In Angular DI system a token can be any reference available in runtime including an instance of a class. So here you have an instance of a class InjectionToken:

export const NG_VALIDATORS = new InjectionToken>('NgValidators');

referenced by the variable NG_VALIDATORS.

Angular DI system introduces a strategy that can redirect the request from one token to another. And this is the strategy that is used here:

export const REQUIRED_VALIDATOR: Provider = {   
    provide: NG_VALIDATORS,   
    useExisting: forwardRef(() => RequiredValidator),   
    multi: true 
};

But what does it redirect to? It redirects to the token referenced by the class RequiredValidator. To understand where RequiredValidator comes from you need to know that Angular adds directive class instances to the element injector. So if you have two directives:

@Directive({selector:'adir'...}) export class ADirective {}
@Directive({selector:'bdir'...}) export class BDirective {}

And apply them like this:

<input adir bdir>

The injector created on these elements will contain the following providers:

[
  { token: ADirective, instance: new ADirective() },
  { token: BDirective, instance: new BDirective() }
]

And so any directive that is added to this element will be able to inject these instances by the class token.

So in the case of required validator when you apply a directive required to an element:

<input required>

in the injector the instance of the RequiredValidator is created by the token RequiredValidator and this is exactly the token to which NG_VALIDATORS redirects.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.