jmurphyau / ember-truth-helpers

Ember HTMLBars Helpers for {{if}} & {{unless}}: not, and, or, eq & is-array
MIT License
706 stars 95 forks source link

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

Open emattias opened 2 years ago

emattias commented 2 years ago

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 😅

tehhowch commented 2 years ago

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:

sukima commented 1 year ago

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}} />
Techn1x commented 1 year ago

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 https://github.com/jmurphyau/ember-truth-helpers/issues/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

NullVoxPopuli commented 1 year ago

does OP want ?? instead of || behavior?

emattias commented 1 year ago

does OP want ?? instead of || behavior?

Yup :)

Techn1x commented 1 year ago

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!

Techn1x commented 1 year ago

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