rambda: defaultsTo shouldn't factor in type
As far as I can tell defaultsTo(defaultArgument, inputArgument) is the only method that provides a way for defaulting to a value (providing some ‘or’ logic). However, the built-in test for inputArgument being the same type as defaultArgument limits the use of this function. It is my opinion that defaultArgument should only be returned if inputArgument is undefined.
I would like to compose a function works the same as Lodash’s get method or Ramda’s pathOr method whereby a value is read from a path through a nested object tree and defaults to a value if this path returns undefined.
import { get } from 'lodash'
import { pathOr } from 'ramda'
import { curry, defaultsTo, path } from 'rambda'
// Tests written with jest
test('lodash get', () => {
expect(get({ a: { b: 2 } }, 'a.b')).toBe(2)
expect(get({ c: { b: 2 } }, 'a.b')).toBeUndefined()
expect(get({ c: { b: 2 } }, 'a.b', 'N/A')).toBe('N/A')
})
test('ramda pathOr', () => {
// From ramda's docs http://ramdajs.com/docs/#pathOr
expect(pathOr('N/A', ['a', 'b'], { a: { b: 2 } })).toBe(2)
expect(pathOr('N/A', ['a', 'b'], { c: { b: 2 } })).toBe('N/A')
})
// There's probably a more elegant way of doing this?
const rambdaPathOr = curry((defaultValue, inputPath, inputValue) =>
defaultTo(defaultValue, path(inputPath, inputValue)))
test('rambda pathOr', () => {
// This first test fails because the value of a.b is 2 (type 'Number')
// and is a different type to the default value 'N/A' (type 'String')
expect(rambdaPathOr('N/A', ['a', 'b'], { a: { b: 2 } })).toBe(2)
expect(rambdaPathOr('N/A', ['a', 'b'], { c: { b: 2 } })).toBe('N/A')
})
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Comments: 15 (7 by maintainers)
😃 I was thinking the whole time that
typedwill be better. So we’ll do that then. As I mentioned earlier I will add the methods before the end of the day.Ignore what I posted above re.
nullandNaNnot being counted as value types for defaulting to a value…I now see where you got you logic fordefaultTofrom:ramda. Apologies!http://ramdajs.com/docs/#defaultTo
I also see where the name comes from, so also ignore my suggestion to rename
defaultTotodefaultOr. You should stick as close toramdaas possible IMO 😃Fair enough re.
defaultTo—I can certainly appreciate it’s use case.Reason I posted this issue is because it is a common design pattern for an
optionsobject to be passed to a function/constructor where certain key values can have multiple types (typically 2).One such example might be a key value on an
optionsobject that can either be afunctionor a falsy value likefalseornull.I have been working on a package called
ig-apithat usesrambda(thank you and kudos btw, it’s really nice). I make use of anoptionsobject that has a couple of key values that can either be transformfunctionsor set tofalseto prevent any transformations from happening. You can read the docs here.By default, some built-in transform functions are used unless the user specifies their own or chooses to disable them by passing
false. In this use case, the default value is typically afunction, but a value offalsecan be provided and is totally valid. WithdefaultsTothis does not work sincefalseis obviously not the same type as the defaultfunctionvalue.Anyway, I digress. With regards to
pathOr, I think it would be better if you could implement this please. While my implementation below certainly works and passes the tests, I expect there might be a better way of writing it usingrambda’s internals? If not, then please go ahead and simple add my implementation: