Angular Validator check if input is number

Viewed 5937

I'm trying to perfom form validation in Angular 9 to check if the value of a certain input is a number (integer or decimal).

I therefore created the following custom validator:

import { AbstractControl, ValidationErrors } from '@angular/forms';

export class NumberValidator {
    static number(control: AbstractControl): ValidationErrors | null {
        if (typeof +control.value === "number") return null;
        return { notANumber: "The value is not a number"};
    };
}

It works fine for an integer or decimal input, telling my that it's valid, however it also tells me that the following string value for example "foo" is valid.

How can I fix that?

5 Answers

+ makes string as NaN which type of is number remove it. or if u have to check one more plus of number then

 if (typeof +control.value === "number" && !isNaN(+control.value)) return null;

"+" convert variable to number ( +control.value )

So in your example you convert control.value to the number, and then check if this variable is a number. In this way it will be always a number

You need to check:

if Number(control.value) == NaN 
// returns true if control.value is string
// else returns parsed number

First of all, the problem comes from the fact that JavaScript returns the type of NaN to be number. So maybe add additional check if the input is also not equal to NaN.

If the user changes the value in the input, the value becomes a string like "123". This is a string but (in your case) it should be valid. So you have to check if this is parsable.

Better: you can set the input type from text to number

<input type="number" ...

Then it's always a number. in addition: you can set the built-in validators min an max: https://angular.io/api/forms/Validators

Drawback is that you cannot use type="number" you need to use type="text" on the input but. But here is my solution as ValidatorFn:

function notANumber(): ValidatorFn {
  return (control: AbstractControl): {[key: string]: any} | null => {
    const value = control.value
    let nV = value
    if (typeof value == 'string') {
      nV = value.replace(',', '.')
    }
    return (Number.isNaN(Number(nV)) && !control.pristine) ? {notANumber: true} : null;
  };
}
Related