ember.js
ember.js copied to clipboard
[Bug] Named block in {{if}} not allowed?
🐞 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
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!
There's also some discussion going on here.
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 :)
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.