ember.js icon indicating copy to clipboard operation
ember.js copied to clipboard

[Bug] Named block in {{if}} not allowed?

Open mydea opened this issue 4 years ago • 4 comments

🐞 Describe the Bug

I am not 100% sure if this is a bug, or if I misunderstand something. Is it not possible to provide an optional named block?

With a slightly simplified component like this:

{{! info-message.hbs }}
<div>
  {{#if (has-block 'title')}}
    {{yield to='title'}}
  {{else
    {{@title}}
  {{/if}}
</div>

<div class='description'>
  {{#if (has-block 'description')}}
    {{yield to='description'}}
  {{else
    {{@description}}
  {{/if}}
</div>

I would expect to be able to do e.g. this:

{{! success-message.hbs
<InfoMessage @title="Success!">
  {{#if @successRoute}}
    <:description>
      <LinkTo @route={{@successRoute}}>Continue</LinkTo>
    </:descirption>
  {{/if}}
</InfoMessage>

However, this gives me the build error:

Unexpected named block nested in a normal block

Is this correct - should this not be supported? If not, what would be the recommended way to realize something like this? Do I really need to repeat the whole component invocation with and without blocks - providing for all possible combinations of attributes and blocks?

🤔 Expected Behavior

I would expect helpers like each or if to work in a way as described in my example.

🌍 Environment

  • Ember: 3.26.1
  • Node.js/npm: 14.15
  • OS: Ubuntu
  • Browser: Edge Chromium

mydea avatar Apr 22 '21 08:04 mydea

Indeed, this is not possible at the moment. Godfrey's emberconf talk covers some scenarios which you can / can't do, including the scenario you are describing. Hope it helps!

bertdeblock avatar Apr 22 '21 08:04 bertdeblock

There's also some discussion going on here.

bertdeblock avatar Apr 22 '21 08:04 bertdeblock

Ah, thank you very much, that's insightful!

Of course a bit of a bummer, would be great to have that. I have some use cases in mind where I would kind of need to "optionally" pass through some named blocks, which are not really possible to do (nicely) without some conditionals. Anyway, now at least I know - it doesn't really say anything about this in the docs, at least I haven't been able to find anything. Would probably be nice to add this somehow - I'd be happy to contribute some updates docs for this if somebody could point me into the right direction :)

mydea avatar Apr 22 '21 08:04 mydea

I run into this issue often. I've had to work around it when doing multiple levels of components where I want to pass a block down to a child component, I have to do stuff like @footerBlock={{has-block 'footer'}} which gets passed through to not yield in the child component. Super annoying.

robclancy avatar Mar 30 '22 03:03 robclancy