title: Reactive Form custom validation not working onBlur, Angular 7
body: <p>I am having issues validating my confirm-pass field onBlur in Angular 7. In my case I have built multiple custom validators which work after the control has been made 'dirty', as well as a directive following Pascal Prechts tutorial which DOES work onBlur when field is only touched, but I would like a pure Reactive solution and Pascal's requires adding to the HTML.</p>
  
  <p>Problem Example: Click into firstName field, immediately tab or click out - built-in required validator fires. 
  Click into confirmPass field, immediately click or tab out; custom validator does NOT fire (even console-logs aren't showing). If you were to type any single character prior to tabbing or clicking out however every version I've made does work, at that point.</p>
  
  <p>I have tried building a validator class with multiple static methods. Controls all used one method ('director') which checks the incoming fieldname and redirected appropriately. This returned an error map or null value directly instead of the function, and of course didn't work. </p>
  
  <p>Next I tried Pascal Prechts tutorial; <a href="https://blog.thoughtram.io/angular/2016/03/14/custom-validators-in-angular-2.html" rel="nofollow noreferrer">https://blog.thoughtram.io/angular/2016/03/14/custom-validators-in-angular-2.html</a> which worked as a directive - I had to type in equalValidator into the HTML however - which I do not want to do.</p>
  
  <p>Finally I tried the Angular suggested function and another I found on StackOverflow, both of which return a function; which itself returns the error map or null. </p>
  
  <p>The FormGroup</p>
  
  <pre><code>ngOnInit() {
      this.regForm = this.fb.group({
          firstName: ["", [Validators.required, Validators.minLength(2), Validators.maxLength(30)]],
          lastName: ["", [Validators.required, Validators.minLength(2), Validators.maxLength(30)]],
          email: ["", [Validators.required, Validators.email]],
          password: ["", [Validators.required, Validators.minLength(8), Validators.maxLength(55)]],
          confirmPass: ["", matchingInputsValidator], 
      }, { updateOn: 'blur' });
      this.lgnForm = this.fb.group({
          lgnEmail: ["", [Validators.required, Validators.email]],
          lgnPass: ["", Validators.required]
      }, { updateOn: 'blur' });
  }
  </code></pre>
  
  <p>Pascals solution which works onBlur, but as a directive only</p>
  
  <pre><code>function validateEqualFactory(compare: string) : ValidatorFn {
      return (c: FormControl) =&gt; {
          // value of confirm password field
          let v = c.value;
  
          // value of compared field - in this case 'password'
          let e = c.root.get(compare);
  
          // Ternary operator -&gt; return null if equal or error map if not equal/password does not exist
          return (e &amp;&amp; v === e.value) ? null : { misMatch: true };
      };
  }
  
  @Directive({
      selector: '[validateEqual][formControl],[validateEqual][formControlName]',
      providers: [
          { provide: NG_VALIDATORS, useExisting: forwardRef(() =&gt; EqualValidator), multi: true }
      ]
  })
  export class EqualValidator implements Validator {
      validator: ValidatorFn;
      constructor() {
          this.validator = validateEqualFactory("password");
      }
      validate(c: FormControl) {
          return this.validator(c);
      }
  }
  </code></pre>
  
  <p>And finally two of the most recent attempts I have made, the first being a variation of Angular documentations official recommendation</p>
  
  <pre><code>export function confirmPassVal(): ValidatorFn {
      return (control: AbstractControl): {[key: string]: any} | null =&gt; {
          console.log("Making it here 1", control);
          const passCtrl = control.root.get('password');
          console.log("Making it here 2: ", passCtrl);
          return (passCtrl &amp;&amp; passCtrl.value === control.value) ? null : {"misMatch" : true };
      }
  }
  
  export const matchingInputsValidator: ValidatorFn = (control: AbstractControl): ValidationErrors | null =&gt; {
      let pass;
      control.root.get('password') ? pass = control.root.get('password').value : pass = null;
      let confirmPass = control.value;
      return pass === confirmPass ? null : { misMatch: true };
  }
  </code></pre>
  
  <p>I expect my function to run when the field is touched and/or dirty, but it is currently only running if the field is dirty. In an ideal world I would like to  be able to extend the Validators or NG_VALIDATORS class with my own custom functions, purely from the FormBuilder declaration. At this point I believe it has something to do with multi-provider, and extending NG_VALIDATORS but....I'm not sure how to do this even if it is the case.</p>