Skip to content

Commit

Permalink
fix(uilts): able to use setDeepValue on undefined/empty object (#732)
Browse files Browse the repository at this point in the history
  • Loading branch information
ghiscoding committed Aug 2, 2022
1 parent d5b5612 commit e370eef
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 5 deletions.
8 changes: 7 additions & 1 deletion packages/utils/src/utils.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -391,8 +391,14 @@ describe('Service/Utilies', () => {
expect(obj).toEqual({ id: 76, user: { firstName: 'John', lastName: 'Doe', addresses: [{ number: 123, street: 'Broadway' }, { number: 234, street: 'Beverly' }] } });
});

it('should be able to set a property even when its original value is undefined', () => {
obj = {};
setDeepValue(obj, 'user.name', 'John');
expect(obj.user.name).toBe('John');
});

it('should be able to update a property of an array inside a complex object', () => {
obj = { id: 1, user: { firstName: 'John', lastName: 'Doe', addresses: [{ street: 'Broadway' }, { number: 234, street: 'Beverly' }] } };
obj = { id: 1, user: { firstName: 'John', lastName: 'Doe', addresses: [{ number: null, street: 'Broadway' }, { number: 234, street: 'Beverly' }] } };
setDeepValue(obj, 'user.addresses.0.number', 111);
expect(obj.user.addresses[0].number).toBe(111);
expect(obj).toEqual({ id: 1, user: { firstName: 'John', lastName: 'Doe', addresses: [{ number: 111, street: 'Broadway' }, { number: 234, street: 'Beverly' }] } });
Expand Down
11 changes: 7 additions & 4 deletions packages/utils/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,10 @@ export function isObject(item: any) {
return (item && typeof item === 'object' && !Array.isArray(item));
}

/** Check if a value has any data (undefined, null or empty string will return false... but false boolean is consider as valid data) */
/**
* Check if a value has any data (undefined, null or empty string will return False...)
* NOTE: a `false` boolean is consider as having data so it will return True
*/
export function hasData(value: any): boolean {
return value !== undefined && value !== null && value !== '';
}
Expand Down Expand Up @@ -216,11 +219,11 @@ export function setDeepValue<T = unknown>(obj: T, path: string | string[], value
}

if (path.length > 1) {
const e = path.shift();
const e = path.shift() as keyof T;
if (obj && e !== undefined) {
setDeepValue(
(obj)[e as keyof T] = (Array.isArray(obj[e as keyof T]) || Object.prototype.toString.call((obj)[e as keyof T]) === '[object Object]')
? (obj)[e as keyof T]
(obj)[e] = (hasData(obj[e]) && (Array.isArray(obj[e]) || Object.prototype.toString.call((obj)[e]) === '[object Object]'))
? (obj)[e]
: {} as T[keyof T],
path,
value
Expand Down

0 comments on commit e370eef

Please sign in to comment.