jmurphyau/ember-truth-helpers

`or` cant be used when or condition value can be `false`

emattias opened this issue · 7 comments

When I want to use a provided @arg whos value can be false and I want to default to true the or helper doesnt work as I need. See this example:

<Foo
	@bar={{or @argThatCanBeFalse true}}
/>

If @argThatCanBeFalse is sent in as false @bar will be resolved to true.

This is because or uses the truthConvert util that does a regular double not operator (!!): https://github.com/jmurphyau/ember-truth-helpers/blob/master/addon/utils/truth-convert.js#L11

Should we change the or helper to only treat undefined (and maybe null) as false values or should we create a new helper. Called something like or-nullish or or-undefined or something that works more like the Nullish coalescing operator (??) ?

I can do a PR if this is something that that maintainers want to add to the project. First question then is if we should change the current or helper or what the new one should then be called 😅

Count me as "Definitely against changing the semantics of {{or}}" The behavior you describe is 100% what I expect to happen, given that {{or}} is for truth testing and not picking a value to use.

I would suggest implementing your own "nullish coalesing" template helper. Possible names:

  • arg-or
  • or-default

Two workarounds:

Out of the box

<Foo @bar={{if (eq @argThatCanBeFalse false) false true}} />

Custom nullish helper

// app/helpers/with-default.js
import { helper } from '@ember/component/helper';

export default helper(([value, defaultValue]) => (value ?? defaultValue));
<Foo @bar={{with-default @argThatCanBeFalse true}} />

I can't seem to replicate the behaviour that the OP is describing. Maybe the and and or helpers were different at some point. The helpers do indeed seem to return the given value, rather than a Boolean cast of the value.

I'm running Ember 4.12 and ember-truth-helpers 3.1.1

{{log (or "OR - PRINTED" true)}}           // OR - PRINTED
{{log (or "OR - PRINTED" false)}}          // OR - PRINTED
{{log (or true "OR - NOT PRINTED")}}       // true
{{log (or false "OR - PRINTED")}}          // OR - PRINTED
{{log (and "AND - NOT PRINTED" true)}}     // true
{{log (and "AND - NOT PRINTED" false)}}    // false
{{log (and true "AND - PRINTED")}}         // AND - PRINTED
{{log (and false "AND - NOT PRINTED")}}    // false

Might be related to #143

given that {{or}} is for truth testing and not picking a value to use.

It depends how you look at it. If we convert the or helper into an equivalent javascript...
const myValue = "OR - PRINTED" || true

I would expect myValue to be the string, rather than true.
image

does OP want ?? instead of || behavior?

does OP want ?? instead of || behavior?

Yup :)

Ah ok. I might have misunderstood the issue, thought it was a bug report rather than a feature request, got confused with the mention of the or helper. Sorry!

I wouldn't be against the addition of a new helper for this. Nullish coalescing is pretty common JavaScript logic these days!