30-seconds-of-code: Value or default

Created on 15 Dec 2017  路  15Comments  路  Source: 30-seconds/30-seconds-of-code

Value or default

when value is 0, this function will return default value

opinions needed

Most helpful comment

Also as it stands, it's quite useless because it takes longer with more overhead than just doing || d.

If we just don't want undefined, null, or NaN, but DO want to use the other falsy values:

const valueOrDefault = (value, d) => 
  (value || [false,0,''].includes(value)) ? value : d

All 15 comments

Also as it stands, it's quite useless because it takes longer with more overhead than just doing || d.

If we just don't want undefined, null, or NaN, but DO want to use the other falsy values:

const valueOrDefault = (value, d) => 
  (value || [false,0,''].includes(value)) ? value : d

I agree that valueOrDefault is kind of... weird. You have many other tools to accomplish it and should really only be checking for undefined(null in some of these cases is considered a specific value you'd want, same with NaN) so that only if something didn't return something when it should have would you need a default. If it returned null, and you wanted null you can't have it with this version.

also many prior arts call it defaultTo and make it a closure so you can use it in many similar cases:

const defaultTo = d => v => v === undefined ?  d : v

More robust case with optional param for allowing you to tell it to use some falsey values

const defaulTo = (default, ...allowed) => value =>  value === undefined || !allowed.includes(value) ?  default : value

I'm a little tired ATM so someone may want to check my allowed version

It is kind of weird and messes up falsey values. We either remove it entirely or refactor it into something useful. As it stands it's a bit of a mess and it's my fault for merging it.

@skatcat31 might be onto something with the first snippet in the last comment, the second one is a bit too excessive in my opinion.

i like it as coalesce similar to the SQL use

const coalesce = (...args) => args.find(_ => ![NaN,undefined,null].includes(_))

or closed over a set of excluded values

const coalesce = (...excludes) => (...args) => args.find(_ => !excludes.includes(_))

Can you provide a quick example of how this works @prodigic? It might be worthwhile to add it in.

@Chalarangelo I agree that the second one is a bit to excessive. It was meant to be a more in depth example of something that behaved a little more like a whitelist. Realistically you should only ever default if undefined since undefined is not a lack of data, but a lack of reference:

  • undefined : no reference, cannot define
  • null : specifically a lack of value at reference
  • NaN : it's Not a Number, this could be a valid value as it's at the reference
  • false : a Boolean. In this case it's a value at the reference
  • 0 : a Number. In this case it's a value at the reference
  • '' : A String. In this case it's a value at the reference

So I think the first one is a little bit more along the lines of what the function describes it doing

If a value does not exist, it will return the default

Contexts are weird man

coalesce(myNickName, myFullName, "");

would return the first value not filtered from the args, so if myNickName===null it return myFullName moving along the parameters til it finds the first item that passes the excludes test.

kind of works like this https://stackoverflow.com/questions/18528468/what-is-the-difference-bewteen-ifnull-and-coalesce-in-mysql except with a broader definition of excluded values.

const coalesce = (...args) => args.find(_ => ![undefined,null].includes(_))
const coalesceFactory = (...excludes = [null,undefined]) => (...args) => args.find(_ => !excludes.includes(_))

taking @skatcat31's observation and defaulting to skipping null/undefined by defualt.

@prodigic It's a cool method, but I think it's a little different than if one does not exist. coalesce is more of a filter function isn't it?

yeah it does have a different goal really, I'll PR it as a separate snippet

@prodigic one last question... are you sure you want to rest and then spread it, or do it against a collection(iterables should be okay) without a rest input so that it isn't something you always have to spread too or collect for, just use an array?

I think we should remove value or default and stick with coalesce. It's a more robust snippet with a clear purpose and the current value or default is a little problematic. Anyone against this?

I am closing the issue for now as it is not about valueOrDefault anymore. The snippet will be removed as it's not really useful right now. If anyone wants to add a coalesce function, I'd be ok with that.

valueOrDefault is kind of a weird function, I'll agree. coalesce is more of a first valid which is really nice, and extremely useful in promise race conditions.

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for any follow-up tasks.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

larrybotha picture larrybotha  路  3Comments

konglx90 picture konglx90  路  6Comments

Lucien-X picture Lucien-X  路  5Comments

Greenheart picture Greenheart  路  3Comments

kingdavidmartins picture kingdavidmartins  路  5Comments