So the min and max constraints on number field in your template based form aren’t working? Users can type in out of range values and the form is still valid. What’s happening?

Let’s say you’ve got a form, named myform, with this input:

<input type="number" [(ngModel)]="model.count" name="count" #count="ngModel" required min="0">

With Angular’s FormsModule, you get the validation on the required attribute basically for free. With no further code, if the user doesn’t fill in this input then count.hasError('required') is true and myform.valid is false. It’s the same with other attributes like pattern, maxLength etc.

However, you don’t get this with min or max.

This actually depends on your version of Angular. Angular 4 briefly had it, but it was removed in version 4.2.3). Apparently was a breaking change for some, but not for me, so let’s get it back.

The angular/forms package still has all the validation code we need, all we have to do is create our own directive. Here it is:

import { Directive, Input, forwardRef } from "@angular/core";
import {
	Validator, AbstractControl, NG_VALIDATORS, Validators, ValidatorFn
	} from "@angular/forms";

@Directive({
    selector: "[min][formControlName],[min][formControl],[min][ngModel]",
    providers: [
        { provide: NG_VALIDATORS,
			useExisting: forwardRef(() => MinDirective),
			multi: true }
    ]
})
export class MinDirective implements Validator {
    private _validator: ValidatorFn;
    @Input() public set min(value: string) {
        this._validator = Validators.min(parseInt(value, 10));
    }

    public validate(control: AbstractControl): { [key: string]: any } {
        return this._validator(control);
    }
}

Create another one for max, add it into the declarations in your module, and you’re all set.