Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support && operator-based conditionals in expressions #51

Open
timwis opened this issue Oct 2, 2016 · 8 comments
Open

Support && operator-based conditionals in expressions #51

timwis opened this issue Oct 2, 2016 · 8 comments

Comments

@timwis
Copy link
Member

timwis commented Oct 2, 2016

What do you think of supporting && operator-based conditionals in interpolated expressions?

Current syntax:

html`<input type="checkbox" name="reviewed" ${data.reviewed ? 'checked' : ''} />`

Proposed syntax to support:

html`<input type="checkbox" name="reviewed" ${data.reviewed && 'checked'} />`

The proposed syntax is simply more succinct, and I believe it's popular in the react ecosystem. While the above example doesn't save much text, the : '' gets in the way more when you have multi-line expressions -- it becomes a trailing piece that is often overlooked.

Currently, the proposed syntax works in bel if the first condition is truthy, but if it is falsy, bel renders its falsy value, and you'd end up with <input type="checkbox" name="reviewed" undefined />. I believe the way around this would be for bel (or maybe hyperx?) to not return anything from an interpolated expression that evaluates to undefined or false. I believe this is how JSX does it.

If for some reason you want to render undefined or false, I think it would be reasonable to convert it to a string (since it's a string once it's in the DOM anyway). I think the exception to this would be the value 0 -- it may be unexpected to have to convert 0 to a string just to render it to the DOM. 0 comes in to play when you want to do ${rows.length && 'foo'} vs. ${rows.length > 0 && 'foo'}.

/cc @yoshuawuyts

@yoshuawuyts
Copy link
Member

I'm on board with this; seems useful enough and can't think of a reason to render the value undefined like ever

@shama
Copy link
Member

shama commented Oct 15, 2016

I don't think we have much control over what happens within the expression of a template literal.

Although I think we should just make it smarter about interpreting booleans for attributes:

html`<input type="checkbox" name="reviewed" checked=${data.reviewed} />`

Would render if true:

<input type="checkbox" name="reviewed" checked="checked" />

and if false:

<input type="checkbox" name="reviewed" />

@vladimirkosmala
Copy link

I agree with this issue, it is actually implemented with Babel/JSX.
Those falsy values should be forgotten (not numbers):

  • false
  • null
  • undefined
  • empty string

Let's compare:

 html`<input value="${data.value ? data.value : ''}" />`
 html`<input value="${data.value}" />`

Declarative conditional

 html`<div>${data.alert ? html`<x-alert />` : ''}</div>`
 html`<div>${data.alert && html`<x-alert />}</div>`

Declarative switch case with three ternary operators

 html`<div>${data.option === 1 ? html`<x-option1 />` : (data.option === 2 ? html`<x-option2 />` : html`<x-option3 />`)}</div>`
 html`<div>
${data.option === 1 && html`<x-option1 />}
${data.option === 2 && html`<x-option2 />}
${data.option === 3 && html`<x-option3 />}
</div>`

The idea is to keep it declarative (no if/else/swtich) and lisible as possible.

What do you think?

@bcomnes
Copy link
Collaborator

bcomnes commented Dec 14, 2017

I’m on board with this idea

@weepy
Copy link

weepy commented May 10, 2019

Are there any advancements on this ? It seems that it is "supported" syntaxwise but a false value is rendered as the string "false".

I think that it would be best to suppress falsey outputs from the expressions - the only issue being rendering "false" from ${false}, but I think this is much less useful than the simpler conditional rendering ^^.

Thoughts ? Should be an easy fix.

@bcomnes
Copy link
Collaborator

bcomnes commented May 10, 2019

I'm going to be diving back into the Choo ecosystem in a big way over the coming months. This is something I would like to see land as well.

@mjstahl
Copy link

mjstahl commented Jun 21, 2019

The type tests in hyperx show that the following values will render empty:

  • null
  • undefined
  • empty string (test is not written, but I wrote a test and will submit a PR)

0 does not render empty thankfully.

I see only two problems making this change.

  1. Change false to render empty would be a breaking change
  2. I have no idea where in the code to make that change because the code is rather dense. So I could use a hand with that (@goto-bus-stop ?)

mjstahl added a commit to mjstahl/hyperx that referenced this issue Jun 21, 2019
@goto-bus-stop
Copy link
Member

@mjstahl yeah, hyperx is not an easy codebase. i'd have to go in with some console.logs myself to be sure, but I think the places to look at would be the places that call strfn and concat. Those functions are used to stringify text and attribute values and to concatenate them if there is a ${templatePart} inside.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants