11

In an Angular2 project I need to validate some inputs. How to easily check if an input value is an integer?

I tried using Number(control.value) which returns 0 for an empty field - not good.

or parseInt(control.value,10) which dis-considers spaces:

If i have something like: 1 space 0,24 = 1 ,024 it returns 1 - which passes the validator with no errors.

Lodash functions like: _.isInteger(control.value) or _.isNumeric(control.value) // return false every time -which is expected, because an input value is a string not a number.

Combining methods like this creates a messy function with many if/else statements, and even then, I'm not sure i get all the edge cases. I definitely need a more straight forward approach. Any ideas?

2 Answers 2

9

This is the cleanest way i found so far:

app.component.html:

<input formControlName="myNumber">

app.component.ts:

export class AppComponent {
    myNumber:FormControl

    constructor(private _ValidatorsService: ValidatorsService){
    }

    this.myNumber= new FormControl('defaultValue',
        [ Validators.required, this._ValidatorsService.isInteger ]);
}

validators.service.ts:

function check_if_is_integer(value){
   // I can have spacespacespace1 - which is 1 and validators pases but
   // spacespacespace doesn't - which is what i wanted.
   // 1space2 doesn't pass - good
   // of course, when saving data you do another parseInt.

   return ((parseFloat(value) == parseInt(value)) && !isNaN(value));

}

@Injectable()
export class ValidatorsService {

   public isInteger = (control:FormControl) => {

        // here, notice we use the ternary operator to return null when value is the integer we want.
        // you are supposed to return null for the validation to pass.

        return check_if_is_integer(control.value) ? null : {
           notNumeric: true
        }
   }

}

Enjoy!

Sign up to request clarification or add additional context in comments.

4 Comments

if(condition){ return true; } else { return false; } ? :) Didn't you mean return (condition); ?
return (parseFloat(value) == parseInt(value)) && !isNaN(value)? #SorryForTheCodeGolfOCD
@ruffin - thanks, I've modified. This post was long time ago when i didn't knew much programming. Now i'm using Haskell and Elm and other beautiful functional stuff - and looking to this messy typescript code gives me a headache :)) If somebody asks - is not me. I wasn't here :))
I think this solution is really nice when you need to re-use custom validators across multiple components. I've recently refactored my code to create a service.
5

Just create a custom validator:

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

export function integer(): ValidatorFn {
  return (control: AbstractControl): ValidationErrors | null => {
    const error: ValidationErrors = { integer: true };

    if (control.value && control.value !== `${parseInt(control.value, 10)}`) {
      control.setErrors(error);
      return error;
    }

    control.setErrors(null);
    return null;
  };
}

then use it in your form:

import { integer } from '...';

form.get('yourControl').setValidators([integer()]);

this will work even with inputs of type text

1 Comment

It works well, but u have to change !== to !=

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.