Angular 2 Custom Validator: check if the input value is an integer?

16,976

Solution 1

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!

Solution 2

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

Share:
16,976

Related videos on Youtube

AIon
Author by

AIon

Updated on June 04, 2022

Comments

  • AIon
    AIon almost 2 years

    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?

  • Jeremy Thille
    Jeremy Thille about 7 years
    if(condition){ return true; } else { return false; } ? :) Didn't you mean return (condition); ?
  • ruffin
    ruffin about 5 years
    return (parseFloat(value) == parseInt(value)) && !isNaN(value)? #SorryForTheCodeGolfOCD
  • AIon
    AIon about 5 years
    @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 :))
  • Ali Celebi
    Ali Celebi over 3 years
    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.
  • Oskar
    Oskar about 3 years
    It works well, but u have to change !== to !=