Skip to main content

ObjectValidator

ObjectValidator is the go-to utility for null-safe checks and type detection. Its IsEmptyOrNull() method is one of the most frequently used functions in any Oidis codebase.

Package: io-oidis-commons

import { ObjectValidator } from "@io-oidis-commons/.../Utils/ObjectValidator.js";

IsEmptyOrNull — The Essential Check​

ObjectValidator.IsEmptyOrNull($value) : boolean

Returns true if the value is null, undefined, empty string "", empty array [], or otherwise "empty". This single method replaces the common pattern of chaining multiple checks:

// ❌ Fragile vanilla approach
if (value !== null && value !== undefined && value !== "") { ... }

// ✅ Oidis approach — handles all edge cases
if (!ObjectValidator.IsEmptyOrNull(value)) { ... }

What counts as "empty":

ObjectValidator.IsEmptyOrNull(null);          // true
ObjectValidator.IsEmptyOrNull(undefined); // true
ObjectValidator.IsEmptyOrNull(""); // true
ObjectValidator.IsEmptyOrNull([]); // true — empty array
ObjectValidator.IsEmptyOrNull("hello"); // false
ObjectValidator.IsEmptyOrNull([1, 2, 3]); // false — non-empty array
ObjectValidator.IsEmptyOrNull(0); // false — zero is a valid value
ObjectValidator.IsEmptyOrNull(false); // false — boolean false is a valid value
Array emptiness

IsEmptyOrNull checks array length internally — no need to add || arr.length === 0 after an IsEmptyOrNull check. The single call covers both null/undefined and empty arrays.

Usage Patterns​

Form validation:

if (ObjectValidator.IsEmptyOrNull($instance.nameInput.Value())) {
$instance.nameInput.MarkInvalid();
$instance.nameInput.InvalidFeedback("Name is required");
validated = false;
}

Null-guard before operations:

const record = await MyRecord.FindById($id);
if (ObjectValidator.IsEmptyOrNull(record)) {
LogIt.Warning("Record not found", $id);
return;
}
// Safe to use record here

New vs existing detection (CRUD pattern):

const record = ObjectValidator.IsEmptyOrNull(this.currentRecord)
? new MyRecord() // Create new
: this.currentRecord; // Edit existing

When to Use vs Optional Chaining​

ScenarioUseExample
Unknown data structureIsEmptyOrNullBackend data, LCP responses
Known structure, optional field?. / ??user?.Name ?? "Anonymous"
User input validationIsEmptyOrNullForm fields, query params
Chained property access?.record?.Group?.Name
Deep unknown nesting + riskIsEmptyOrNull + try/catchExternal API responses
Rule of thumb

Use ObjectValidator.IsEmptyOrNull() when you're not sure about the data structure. Use ?. and ?? when you know the structure but a field might be absent.

Type Checking Methods​

ObjectValidator.IsSet($value) : boolean        // Not undefined (does NOT check for null)
ObjectValidator.IsString($value) : boolean // typeof === "string"
ObjectValidator.IsDigit($value) : boolean // typeof === "number" (not NaN)
ObjectValidator.IsBoolean($value) : boolean // typeof === "boolean"
ObjectValidator.IsObject($value) : boolean // typeof === "object" (not null, not array)
ObjectValidator.IsFunction($value) : boolean // typeof === "function"
ObjectValidator.IsClass($value) : boolean // Is a class constructor
ObjectValidator.IsArray($value) : boolean // Native array OR ArrayList instance
ObjectValidator.IsError($value) : boolean // Error instance check
IsSet does NOT check for null

IsSet() only checks against undefined. It returns true for null values, which leads to runtime crashes when accessing properties on null. If a variable can be null, use !IsEmptyOrNull() instead.

// ❌ BUG — IsSet(null) returns true, then crashes on null.property
let instance : MyClass | null = null;
if (ObjectValidator.IsSet(instance)) {
instance.DoSomething(); // TypeError: Cannot read properties of null
}

// ✅ CORRECT — IsEmptyOrNull catches both null and undefined
if (!ObjectValidator.IsEmptyOrNull(instance)) {
instance.DoSomething(); // safe
}

Examples​

if (ObjectValidator.IsString($value)) {
// Safe to call string methods
const lower = $value.toLowerCase();
}

if (ObjectValidator.IsArray($items)) {
// Safe to iterate — works for both native arrays and ArrayList
$items.forEach(($item) => { ... });
}

if (ObjectValidator.IsDigit($price) && $price > 0) {
// Valid positive number
}

if (ObjectValidator.IsError($result)) {
LogIt.Error("Operation failed", $result);
}

Numeric Type Distinction​

ObjectValidator provides three methods for numeric validation, each with different precision:

ObjectValidator.IsDigit($value) : boolean       // Any number (integer or decimal)
ObjectValidator.IsInteger($value) : boolean // Whole numbers only (no decimal part)
ObjectValidator.IsDouble($value) : boolean // Has decimal part specifically
Common footgun

IsDigit accepts any numeric value including decimals. If you need to ensure a whole number (e.g., for array indices, counts, or IDs), use IsInteger instead.

Behavior comparison:

ValueIsDigitIsIntegerIsDouble
42truetruefalse
42.5truefalsetrue
0truetruefalse
3.0truetruefalse
"42"falsefalsefalse
NaNfalsefalsefalse
nullfalsefalsefalse
// ❌ Wrong — allows decimals for an array index
if (ObjectValidator.IsDigit($index)) {
items[$index]; // Could crash if $index is 2.5
}

// ✅ Correct — ensures whole number
if (ObjectValidator.IsInteger($index)) {
items[$index]; // Safe
}

Array Type Distinction​

ObjectValidator.IsNativeArray($value) : boolean  // Strict Array.isArray() — native JS arrays only
ObjectValidator.IsArray($value) : boolean // Native arrays OR Oidis ArrayList instances

Use IsArray when you want to accept both native arrays and ArrayList (the Oidis typed collection). Use IsNativeArray when you specifically need a plain JavaScript array:

// Accept any array-like collection
if (ObjectValidator.IsArray($items)) {
// Works for [] and ArrayList
}

// Strict native array check (e.g., before JSON.stringify or Array.from)
if (ObjectValidator.IsNativeArray($items)) {
// Guaranteed plain JS array
}

Hexadecimal Validation​

ObjectValidator.IsHexadecimal($value : string) : boolean

Returns true if the string is a valid hexadecimal format:

ObjectValidator.IsHexadecimal("FF00AA");  // true
ObjectValidator.IsHexadecimal("#FF00AA"); // true
ObjectValidator.IsHexadecimal("0xFF00"); // true
ObjectValidator.IsHexadecimal("GHIJKL"); // false

Complete Method Reference​

MethodReturns true when
IsEmptyOrNull($v)null, undefined, "", empty array [], or empty
IsSet($v)Not undefined (does not check for null)
IsString($v)typeof === "string"
IsDigit($v)Any number (not NaN)
IsInteger($v)Whole number (no decimal part)
IsDouble($v)Number with decimal part
IsBoolean($v)typeof === "boolean"
IsObject($v)Object (not null, not array)
IsFunction($v)typeof === "function"
IsClass($v)Class constructor
IsArray($v)Native array or ArrayList
IsNativeArray($v)Array.isArray() strictly
IsHexadecimal($v)Valid hex string
IsError($v)Error instance

Vanilla JS Equivalents​

ObjectValidatorVanilla JSWhy Prefer ObjectValidator
IsEmptyOrNull($v)$v != null && $v !== ""Handles more edge cases
IsSet($v)$v !== undefinedOnly checks undefined — use !IsEmptyOrNull for null+undefined
IsString($v)typeof $v === "string"Consistent with other checks
IsDigit($v)typeof $v === "number" && !isNaN($v)Handles NaN
IsInteger($v)Number.isInteger($v)Consistent API
IsDouble($v)typeof $v === "number" && $v % 1 !== 0Consistent API
IsArray($v)Array.isArray($v)Also accepts ArrayList
IsNativeArray($v)Array.isArray($v)Equivalent — use for strict check
IsError($v)$v instanceof ErrorConsistent API

For simple type checks where you're confident about the data, vanilla typeof and ?. are acceptable. Use ObjectValidator when robustness matters — especially for user input and external data.


See also: Utilities Overview | StringUtils | JsonUtils | Logging