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
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
| Scenario | Use | Example |
|---|---|---|
| Unknown data structure | IsEmptyOrNull | Backend data, LCP responses |
| Known structure, optional field | ?. / ?? | user?.Name ?? "Anonymous" |
| User input validation | IsEmptyOrNull | Form fields, query params |
| Chained property access | ?. | record?.Group?.Name |
| Deep unknown nesting + risk | IsEmptyOrNull + try/catch | External API responses |
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() 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
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:
| Value | IsDigit | IsInteger | IsDouble |
|---|---|---|---|
42 | true | true | false |
42.5 | true | false | true |
0 | true | true | false |
3.0 | true | true | false |
"42" | false | false | false |
NaN | false | false | false |
null | false | false | false |
// ❌ 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
| Method | Returns 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
| ObjectValidator | Vanilla JS | Why Prefer ObjectValidator |
|---|---|---|
IsEmptyOrNull($v) | $v != null && $v !== "" | Handles more edge cases |
IsSet($v) | $v !== undefined | Only 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 !== 0 | Consistent API |
IsArray($v) | Array.isArray($v) | Also accepts ArrayList |
IsNativeArray($v) | Array.isArray($v) | Equivalent — use for strict check |
IsError($v) | $v instanceof Error | Consistent 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