3

How can I pass a parameter to a custom validator written for a Template Driven Form in Angular 7?

I've got the following code put together from multiple other questions and blog posts, but most center around Reactive forms rather than tempalte.

import { AbstractControl, ValidatorFn, NG_VALIDATORS, Validator, FormControl } from '@angular/forms';
import { Directive, Input } from '@angular/core';

// validation function
function validateMinValue(minValue: number): ValidatorFn {
    return (c: AbstractControl) => {

        console.log(minValue); 
        return null;
    }
}

@Directive({
    selector: '[minValue][ngModel]',
    providers: [
        { provide: NG_VALIDATORS, useExisting: MinValueValidator, multi: true }
    ]
})
export class MinValueValidator implements Validator {
    @Input("minValue") minValue;
    validator: ValidatorFn;

    constructor() {
        this.validator = validateMinValue(this.minValue);
    }

    validate(c: FormControl) {
        return this.validator(c);
    }
}

How could I access the value passed to minValue in an input like this

<input type="text" name="testInput" class="form-control"
        [(ngModel)]="testValue" required
        currencyMask [options]="{ thousands: ',', decimal: '.' }"
        minValue="100">
Danyx
  • 574
  • 7
  • 34
  • [Through directives only](https://angular.io/guide/form-validation#adding-to-template-driven-forms) –  Sep 26 '19 at 14:26
  • Have you tried to use ngOnInit instead of constructor to initialize validator? – yurzui Sep 26 '19 at 14:27

1 Answers1

2

You should be using ngOnInit hook to initialize validator since there is no Input property initialized in constructor yet.

ngOnInit() {
   this.validator = validateMinValue(this.minValue);
}

This way the initialized value will be passed to your validator.

Another way is to simple define validator within your custom directive and take minValue from current context this:

export class MinValueValidator implements Validator {
    @Input("minValue") minValue;

    validate(c: FormControl) {
        console.log(this.minValue); 
        return null;
    }
}
yurzui
  • 205,937
  • 32
  • 433
  • 399
  • While true, it doesn't answer the question about *how* to pass the parameter to the validator –  Sep 26 '19 at 14:31
  • 1
    @Maryannah, OP is doing the right thing, now it's successfully passed when moving code into `OnInit` like in answer :) https://stackblitz.com/edit/angular-4ur8ju?file=src/app/app.component.html And to the OP: notice that you need to use `[minValue]="100"` if you want to pass a number, which I assume you want. – AT82 Sep 26 '19 at 18:30