4

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?

1
  • + makes string as NaN which type of is number remove it Commented May 17, 2020 at 10:32

5 Answers 5

5

+ 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;
Sign up to request clarification or add additional context in comments.

Comments

1

"+" 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

Comments

0

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.

Comments

0

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

Comments

0

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;
  };
}

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.