Showing posts with label validation. Show all posts
Showing posts with label validation. Show all posts

Friday, March 7, 2025

JavaScript Boolean Object

It has been a looooooong time since I posted. Not because I haven't had a ton to post about, but because at my core I'm super lazy. Anyway, here's a quick hitter on how to check if every property on an object is true using the Boolean function in JavaScript.

return Object.values(this.data.modal.validation).every(Boolean);

You do need to watch out for a couple of things if you want to use this. First, because of type coercion in JavaScript, an object that has pretty much any kind of data on a property will count as true. So if you had an object with a name property that had a value of "Mickey", that's true in this scenario. Second (and related), if you have a property with a value of 0 it will count as false, again due to type coercion.

I'm using this to check an object that only has boolean properties and it works very well.

Tuesday, February 11, 2020

Masked Input Length Validation in Angular

We use angular2-text-mask to mask some of our inputs at work (so phone number fields show parentheses and a hyphen, for example). I discovered today that using the built-in Angular minLength validator doesn't work with the text mask because the masked value meets the length criteria. So I wrote my own validator based on the built-in one that accepts an optional array of characters to replace and then only returns true if the modified length (that is, the length of the string after removing masking characters) is long enough (or short enough, depending on which validator you use). You know what? Let me just show you.

   1:  import { Injectable } from '@angular/core';
   2:  import { AbstractControl, ValidationErrors, ValidatorFn } from '@angular/forms';
   3:  
   4:  @Injectable({
   5:    providedIn: 'root'
   6:  })
   7:  export class MaskedLengthValidator {
   8:    static minLength(minLength: number, replace?: Array<string>): ValidatorFn {
   9:      return (control: AbstractControl): ValidationErrors | null => {
  10:        if (this.isEmptyInputValue(control.value)) {
  11:          return null;
  12:        }
  13:  
  14:        let value = control.value;
  15:  
  16:        if (!!replace && !!replace.length) {
  17:          replace.forEach(c => {
  18:            var regEx = new RegExp(c, 'g');
  19:            value = value.replace(regEx, "");
  20:          });
  21:        } else {
  22:          value = control.value.replace(/_/g, "");
  23:        }
  24:  
  25:        const length: number = value ? value.length : 0;
  26:        return length < minLength ?
  27:          {'minlength': {'requiredLength': minLength, 'actualLength': length}} :
  28:          null;
  29:      };
  30:    }
  31:  
  32:    static maxLength(maxLength: number, replace?: Array<string>): ValidatorFn {
  33:      return (control: AbstractControl): ValidationErrors | null => {
  34:        let value = control.value;
  35:  
  36:        if (!!replace && !!replace.length) {
  37:          replace.forEach(c => {
  38:            var regEx = new RegExp(c, 'g');
  39:            value = value.replace(regEx, "");
  40:          });
  41:        } else {
  42:          value = !!value ? control.value.replace(/_/g, "") : value;
  43:        }
  44:  
  45:        const length: number = value ? value.length : 0;
  46:        return length > maxLength ?
  47:          {'maxLength': {'requiredLength': maxLength, 'actualLength': length}} :
  48:          null;
  49:      };
  50:    }
  51:  
  52:    static isEmptyInputValue(value: any): boolean {
  53:      // we don't check for string here so it also works with arrays
  54:      return value == null || value.length === 0;
  55:    }
  56:  }
  57:  

So that's the validator. The simple way to use it is like this:
   1:    ngOnInit() {
   2:      this.someForm = this.formBuilder.group({
   3:        phoneNumber: [null, [Validators.required, MaskedLengthValidator.minLength(10), MaskedLengthValidator.maxLength(10)]]
   4:      });
   5:    }

And if you have placeholders in your mask other than underscores you can use it like this:
   1:    ngOnInit() {
   2:      this.someForm = this.formBuilder.group({
   3:        phoneNumber: [null, [Validators.required, MaskedLengthValidator.minLength(10, ['-']), MaskedLengthValidator.maxLength(10, ['-'])]]
   4:      });
   5:    }

This is pretty straightforward once you think about it. Now you don't have to think about.