@apphp/object-resolver
v3.2.0
Published
Provides general functionality for dealing with nested properties in JavaScript objects.
Maintainers
Readme
Object Resolver
Provides general functionality for dealing with nested properties in JavaScript objects
Available methods:
- isEqual
- filterObject
- removeUndefinedProperties
- hasNestedProperty
- getNestedProperty
- fetchLastNestedProperty
- setNestedProperty
- deleteNestedProperty
- setNestedPropertyImmutable
- deleteNestedPropertyImmutable
- cloneObject
- cloneStructure
Install
Install / Uninstall with npm:
$ npm install @apphp/object-resolverUninstall
$ npm uninstall @apphp/object-resolverRun Tests
$ npm run testAfter tests running coverage report can be found in coverage directory
Run ESLint
To perform ESlint check run following command:
$ npm run eslintTo fix issues, found by ESLint run:
$ npm run eslint-fixUsage
Require package:
// by using require
const resolver = require('@apphp/object-resolver');
// by using import
//import resolver from "@apphp/object-resolver";
// by using object destructor
//const {cloneObject} = require('dist/object-resolver');isEqual(value1, value2)
Compares two values for deep equality.
isEqual() performs a recursive deep comparison and supports primitives, arrays, plain objects, and common built-in JavaScript types.
Behavior highlights:
- Object key order does not matter (
{ a: 1, b: 2 }equals{ b: 2, a: 1 }) - Nested objects/arrays are compared deeply
- Supports
Date,RegExp,Map,Set,ArrayBuffer, and typed arrays - Handles circular references safely
- Uses strict prototype checks (values with different prototypes are not equal)
resolver.isEqual({ a: 1, b: { c: 2 } }, { b: { c: 2 }, a: 1 }); // true
resolver.isEqual([1, 2, 3], [1, 2, 4]); // false
resolver.isEqual(new Date('2023-01-01'), new Date('2023-01-01')); // true
resolver.isEqual(/abc/gi, /abc/g); // false
resolver.isEqual(new Set([1, { a: 2 }]), new Set([{ a: 2 }, 1])); // true
const x = { a: 1 };
const y = { a: 1 };
x.self = x;
y.self = y;
resolver.isEqual(x, y); // truefilterObject(obj, predicate)
Filters the properties of an object based on a predicate function
const filtered = resolver.filterObject({ a: 1, b: 2, c: 3, d: 4 }, (value, key) => value % 2 === 0);removeUndefinedProperties(obj)
Removes properties with undefined values from an object
const cleaned = resolver.removeUndefinedProperties({ a: 1, b: undefined, c: { d: 4, e: undefined } });hasNestedProperty(obj, propertyPath)
Checks whether a nested property exists and returns a boolean result
const exists = resolver.hasNestedProperty(obj, 'innerObject.deepObject.value'); // true/falsegetNestedProperty(objParam, propertyPath, defaultValue)
Get nested property exists and if not empty perform some action
const prop = resolver.getNestedProperty(obj, 'innerObject.deepObject.value')
if (prop) {
// ...
}fetchLastNestedProperty(obj, path)
Fetch last chained nested property
const prop = resolver.fetchLastNestedProperty(obj, 'prop');setNestedProperty(obj, path, value)
Set a deeply nested property in an object (mutates the original object)
Behavior notes:
- Mutates
objin place; returnsundefined - Creates missing intermediate objects on the path when needed
pathmay be a dot-separated string or an array of keys- Throws an error for invalid path type (not string/array)
- Throws an error for protected keys:
__proto__,constructor,prototype - Supports numeric object keys; limited bracket-style handling is supported by current implementation
const prop = resolver.setNestedProperty(obj, 'user.profile.name', 'John Doe');deleteNestedProperty(obj, path)
Delete a deeply nested property in an object (mutates the original object)
Behavior notes:
- Mutates
objin place; returnsundefined - If
objisnullor not an object, it does nothing - If any intermediate path segment is missing, it exits early (no throw)
- For array targets, it removes items via
splice(index, 1) - For object targets, it uses
deleteon the last key
const prop = resolver.deleteNestedProperty(obj, 'user.profile.name', 'John Doe');setNestedPropertyImmutable(obj, path, value)
Set a deeply nested property without mutating the original object
const updatedObj = resolver.setNestedPropertyImmutable(obj, 'user.profile.name', 'John Doe');deleteNestedPropertyImmutable(obj, path)
Delete a deeply nested property without mutating the original object
const updatedObj = resolver.deleteNestedPropertyImmutable(obj, 'user.profile.name');cloneObject(obj)
Deep cloning of object
const objCopy = resolver.cloneObject(obj);cloneStructure(obj, options)
Deep cloning of structure (node > v17)
const structureCopy = resolver.cloneStructure(obj, options);Mutation and edge cases
Mutates input
setNestedPropertydeleteNestedProperty
Returns new value (non-mutating)
filterObjectremoveUndefinedPropertiessetNestedPropertyImmutabledeleteNestedPropertyImmutablecloneObjectcloneStructure
Read-only helpers (no mutation)
isEqualhasNestedPropertygetNestedPropertyfetchLastNestedProperty
Edge-case quick reference
hasNestedProperty(obj, path)returnsfalsewhenobjorpathis missing/falsygetNestedProperty(obj, path, defaultValue)returnsdefaultValueonly when resolved value isundefinedsetNestedPropertythrows for invalid path type and protected keysdeleteNestedPropertysafely no-ops for invalid root/non-existing intermediate path
Examples
const obj1 = { a: 1, b: { c: 2 } };
const obj2 = { a: 1, b: { c: 2 } };
const compareResult = resolver.isEqual(obj1, obj2);const original = { a: 1, b: 2, c: 3, d: 4 };
const filtered = resolver.filterObject(original, (value, key) => value % 2 === 0);
console.log(filtered); const original = { a: 1, b: undefined, c: { d: 4, e: undefined } };
const cleaned = resolver.removeUndefinedProperties(original);const obj = {
innerObject: {
deepObject: {
value: 'Here I am'
}
}
};
console.log(resolver.hasNestedProperty(obj, 'innerObject.deepObject.value')); // true
console.log(resolver.hasNestedProperty(obj, 'innerObject.deepObject.wrongValue')); // false
console.log(resolver.getNestedProperty(obj, 'innerObject.deepObject.value')); // 'Here I am'
console.log(resolver.getNestedProperty(obj, 'innerObject.deepObject.wrongValue')); // undefined
console.log(resolver.getNestedProperty(obj, 'innerObject.deepObject.wrongValue.oneMore', 'Oh-h-h')); // 'Oh-h-h'const obj = {
innerObject: {
deepObject: [
{ name: 'John' },
{ name: 'Nick' },
{ name: 'Ron' }
]
}
};
console.log(resolver.hasNestedProperty(obj, 'innerObject.deepObject.0.name')); // true
console.log(resolver.getNestedProperty(obj, 'innerObject.deepObject.1.name')); // 'Nick'const obj = { role: { role: { role: 'student' } }};
const role = resolver.fetchLastNestedProperty(obj, 'role');const obj = {'a':{'b':2}, 'c':3};
const objCopy = resolver.cloneObject(obj);License
MIT
