JavaScript Object Utilities
js-object-utilities is a lightweight JavaScript package providing a collection of helper methods designed for working with nested objects. It simplifies common tasks like accessing, setting, deleting, and transforming deeply nested properties using dot-notation paths. Currently at version 2.2.1, the library maintains a stable release cadence. Key differentiators include its focus on handling complex object structures gracefully, providing utilities for deep equality checks, detecting circular references, and clearing empty objects, which are often overlooked in more general-purpose utility libraries. It ships with TypeScript type definitions, enhancing development experience for TypeScript users.
Common errors
-
TypeError: objectutils.get is not a function
cause Attempting to use named imports (e.g., `import { get } from 'js-object-utilities'`) when the package only provides a default export object.fixUse the correct default import pattern: `import objectUtils from 'js-object-utilities';` then access methods as `objectUtils.get(obj, key);`. -
Cannot read properties of undefined (reading 'hello')
cause This error occurs when a property is accessed on an `undefined` or `null` object during a nested path traversal, indicating an intermediate path segment does not exist. While `objectUtils.get` handles non-existent paths by returning `undefined`, this error typically arises when you try to access a sub-property of the `undefined` result from `get` without null-checking.fixEnsure the object passed to `objectUtils.get` is not `undefined` or `null`. Always check the return value of `objectUtils.get` before attempting further property access, e.g., `const value = objectUtils.get(obj, 'path'); if (value !== undefined) { /* use value */ }`. -
RangeError: Maximum call stack size exceeded
cause Attempting to stringify (`JSON.stringify`) or deeply clone an object that contains circular references without first detecting and handling them.fixBefore performing operations sensitive to circular references, use `objectUtils.isCircular(obj)` to check for their presence. If detected, you'll need to either remove the circular reference, transform the object, or use a custom replacer function for `JSON.stringify`.
Warnings
- gotcha Several utility functions like `set`, `delete`, and `clearEmpties` mutate the original object directly. Be mindful of this behavior when working with immutable state patterns or shared objects.
- gotcha The README example for `objectutils.pick` incorrectly shows `objectutils.delete` being called, but the description correctly states `pick` returns a new object with selected keys. Rely on the description and the expected behavior of a 'pick' function rather than the erroneous code snippet in the README.
- gotcha The `isCircular` function is crucial for preventing infinite loops or stack overflows when stringifying or processing objects with circular references. Failing to check for circularity can lead to runtime errors in JSON serialization or other recursive operations.
Install
-
npm install js-object-utilities -
yarn add js-object-utilities -
pnpm add js-object-utilities
Imports
- objectUtils
import { objectUtils } from 'js-object-utilities';import objectUtils from 'js-object-utilities';
- objectUtils (CommonJS)
const { get } = require('js-object-utilities');const objectUtils = require('js-object-utilities'); - Type definitions
import type { ObjectUtilities } from 'js-object-utilities';
Quickstart
import objectUtils from 'js-object-utilities';
interface MyObject {
data: {
hello: string;
space?: string;
node?: string;
otherData?: Record<string, unknown>;
};
array?: { first: number };
array2?: MyObject;
}
let myObject: MyObject = {
data: {
hello: 'world',
space: 'travel',
node: 'npm',
otherData: {}
}
};
console.log('Original object:', JSON.stringify(myObject, null, 2));
// Get a nested value
const helloValue = objectUtils.get(myObject, 'data.hello');
console.log(`Value of 'data.hello': ${helloValue}`); // Expected: world
// Set a nested value
objectUtils.set(myObject, 'data.hello', 'universe');
console.log('After setting data.hello:', JSON.stringify(myObject, null, 2)); // Expected: universe
// Pick specific keys to create a new object
const pickedObject = objectUtils.pick(myObject, ['data.hello', 'data.space']);
console.log('Picked object:', JSON.stringify(pickedObject, null, 2)); // Expected: { "data": { "hello": "universe", "space": "travel" } }
// Delete a nested key
objectUtils.delete(myObject, 'data.node');
console.log('After deleting data.node:', JSON.stringify(myObject, null, 2));
// Clear empty objects
objectUtils.clearEmpties(myObject);
console.log('After clearing empties:', JSON.stringify(myObject, null, 2)); // 'otherData' should be removed
// Check for circularity
let circularObject: MyObject = {
data: { hello: 'circular' }
};
circularObject.array2 = circularObject; // Create circular reference
console.log('Is circular object circular?', objectUtils.isCircular(circularObject)); // Expected: true