diff --git a/docs/object/get.mdx b/docs/object/get.mdx index 9a089994e..45bdecd60 100644 --- a/docs/object/get.mdx +++ b/docs/object/get.mdx @@ -8,6 +8,9 @@ since: 12.1.0 Given any value and a select function to get the desired attribute, returns the desired value or a default value if the desired value couldn't be found. +> **Note:** Since v12.1.0, `get` will return the `defaultValue` if the resolved value is `undefined` **or** `null`. +> Falsy values like `0`, `''`, or `false` are preserved and will not be replaced by the default. + ```ts import * as _ from 'radashi' @@ -26,4 +29,12 @@ const fish = { _.get(fish, 'sizes[0].range[1]') // 18 _.get(fish, 'sizes.0.range.1') // 18 _.get(fish, 'foo', 'default') // 'default' -``` + +// null and undefined both trigger default: +_.get({ name: null }, 'name', 'Unknown') // 'Unknown' +_.get({}, 'name', 'Unknown') // 'Unknown' + +// falsy but non-nullish values remain unchanged: +_.get({ age: 0 }, 'age', 99) // 0 +_.get({ text: '' }, 'text', 'N/A') // '' +_.get({ active: false }, 'active', true) // false diff --git a/src/object/get.ts b/src/object/get.ts index e0140f4fe..d06862087 100644 --- a/src/object/get.ts +++ b/src/object/get.ts @@ -23,10 +23,7 @@ export function get( const segments = path.split(/[\.\[\]]/g) let current: any = value for (const key of segments) { - if (current === null) { - return defaultValue as TDefault - } - if (current === undefined) { + if (current == null) { return defaultValue as TDefault } const unquotedKey = key.replace(/['"]/g, '') @@ -35,7 +32,7 @@ export function get( } current = current[unquotedKey] } - if (current === undefined) { + if (current == null) { return defaultValue as TDefault } return current diff --git a/tests/object/get.test.ts b/tests/object/get.test.ts index eb9ff6ccd..484700c5f 100644 --- a/tests/object/get.test.ts +++ b/tests/object/get.test.ts @@ -42,4 +42,21 @@ describe('get', () => { expect(_.get(jay, 'friends[0][name]')).toBe('carl') expect(_.get(jay, 'friends[0].friends[0].friends[0].age', 22)).toBe(22) }) + + test('returns default when final resolved value is null', () => { + const obj = { a: { b: null } } + expect(_.get(obj, 'a.b', 123)).toBe(123) + }) + + test('does not replace falsy non-nullish values with default', () => { + const obj = { a: 0, b: '', c: false } + expect(_.get(obj, 'a', 123)).toBe(0) + expect(_.get(obj, 'b', 'abc')).toBe('') + expect(_.get(obj, 'c', true)).toBe(false) + }) + + test('null nested property returns default', () => { + const obj = { x: { y: null } } + expect(_.get(obj, 'x.y', 'DEF')).toBe('DEF') + }) })