# Failsafe {{component}} helper

**URL:** <https://discuss.emberjs.com/t/failsafe-component-helper/8705>\
**Category:** Uncategorized\
**Created:** [August 28, 2015, 6:40pm UTC](https://discuss.emberjs.com/t/failsafe-component-helper/8705 "2015-08-28T18:40:06Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![xcambar](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/xcambar/32/11309_2.png) [@xcambar](https://discuss.emberjs.com/u/xcambar)\
**Post date:** [August 28, 2015, 6:40pm UTC](https://discuss.emberjs.com/t/failsafe-component-helper/8705/1 "2015-08-28T18:40:06Z")

</div>

Hi, I need to use the `{{component componentName}}` helper (or an equivalent) but I need to extend it so it can yield if lookup fails.

Ideally something like that:

```auto
{#component chartType data=chartData}
  Sorry, but we can't display your data as a {{humanReadableChartType}}.
{/component}

```

I have been struggling with this the whole day:

1. with a helper-based approch - not being able to lookup components in a helper,
2. with a component-based approch - not being able to pass an arbitrary number of arguments from a component to its child without compiling a new template (nope, I won’t be satisfied with that).

I am running out of ideas. I really hope some of you know if/how that could be achieved (@lukemelia? You’ve made the helper, so maybe… 🙏 ) or can point me to some code or ember-ci addon.

Thanks for reading!

---

<div class="post-metadata">

**Author:** ![brian\_ally](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/brian_ally/32/10571_2.png) [@brian\_ally](https://discuss.emberjs.com/u/brian_ally)\
**Post date:** [August 29, 2015, 12:59am UTC](https://discuss.emberjs.com/t/failsafe-component-helper/8705/2 "2015-08-29T00:59:08Z")

</div>

++ for this. A couple of months ago I tried dealing with the same thing. Also for charts (d3), as it happens. What I tried was something like (from memory):

```
componentExists: function() {
  return this.container.lookup("component:" + this.get("model.chartType")) !== undefined;
}.property("chartType")

{{#if componentExists}}
  {{component chartType ...}}
{{else}}
  {{mystery-component name=chartType}}
{{/if}}

```

The mystery-component would just display a message similar to what you have. However, Ember did not like my computed property. As soon as i added it Ember failed, complaining that a completely unrelated computed property was null. I mean, it was failing in a completely unrelated bit of code. I eventually gave up. Perhaps if i refactor to use Ember.computed everywhere it will work. Maybe someday.

---

<div class="post-metadata">

**Author:** ![xcambar](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/xcambar/32/11309_2.png) [@xcambar](https://discuss.emberjs.com/u/xcambar)\
**Post date:** [August 29, 2015, 1:37am UTC](https://discuss.emberjs.com/t/failsafe-component-helper/8705/3 "2015-08-29T01:37:14Z")

</div>

I realised that the syntax I proposed is incorrect: in its current form, the `yield` is transfered to the rendered component (when found).

Obviously, a part of the solution involves its syntax: an `if/else`-like seems relevant, as in:

```
{{#component chartType data=chartData}}
  I will yield in the component if it exists
{{#else}}
  Sorry, but we can't display your data as a {{humanReadableChartType}}.
{{/component}}

```

Or does it?

---

<div class="post-metadata">

**Author:** ![xcambar](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/xcambar/32/11309_2.png) [@xcambar](https://discuss.emberjs.com/u/xcambar)\
**Post date:** [August 30, 2015, 5:16pm UTC](https://discuss.emberjs.com/t/failsafe-component-helper/8705/4 "2015-08-30T17:16:49Z")

</div>

I implemented it the `{{component}}` helper itself in this PR: [https://github.com/emberjs/ember.js/pull/12250](https://github.com/emberjs/ember.js/pull/12250)

---

<div class="post-metadata">

**Author:** ![xcambar](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/xcambar/32/11309_2.png) [@xcambar](https://discuss.emberjs.com/u/xcambar)\
**Post date:** [August 31, 2015, 10:56am UTC](https://discuss.emberjs.com/t/failsafe-component-helper/8705/5 "2015-08-31T10:56:15Z")

</div>

@mmun rightfully pointed out that it would break `{{else}}` blocks for components.

So I’ve published instead [ember-cli-if-component](https://github.com/xcambar/ember-cli-if-component) that implements the feature.

Hope this helps, feedback more than welcome!

---

<div class="post-metadata">

**Author:** ![ef4](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/ef4/32/13470_2.png) [@ef4](https://discuss.emberjs.com/u/ef4)\
**Post date:** [August 31, 2015, 7:24pm UTC](https://discuss.emberjs.com/t/failsafe-component-helper/8705/6 "2015-08-31T19:24:37Z")

</div>

Thanks for this addon, I think it’s a good idea. But you have a bug: this will only find components that have a Javascript file. Components that only have a template will not be returned by `container.lookup('component:' + name)`.

Also, you can simplify your addon substantially by providing a helper instead of a component, and just relying on the normal `if/else`

```
{{#if (is-component whichComponent) }}
  {{component whichComponent}}
{{else}}
  Sorry!
{{/if}}

```

Here is a complete helper that solves both issues. Drop this into `app/helpers/is-component.js` and the above snippet will work:

```nohighlight
export default Ember.Helper.extend({
  compute([name]) {
    return this.container.lookup('component-lookup:main').lookupFactory(name, this.container);
  }
})

```

Helpers are awesome, and people should reach for them more often. 😄

The helper can be used in many different places that a component can’t go. For example:

```
<div class="{{#unless (is-component thing) 'chart-unavailable'}}">

```

---

<div class="post-metadata">

**Author:** ![xcambar](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/xcambar/32/11309_2.png) [@xcambar](https://discuss.emberjs.com/u/xcambar)\
**Post date:** [August 31, 2015, 11:45pm UTC](https://discuss.emberjs.com/t/failsafe-component-helper/8705/7 "2015-08-31T23:45:28Z")

</div>

Indeed the code is significantly smaller. So small it may not require its own addon, but I’ve nonetheless updated the repo for the record and because it will probably come in handy to someone else.

Thank you for the advice and thorough answer, it helped a lot and I’ve learnt many things in the process!

---

<div class="post-metadata">

**Author:** ![lamboo](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/lamboo/32/10009_2.png) [@lamboo](https://discuss.emberjs.com/u/lamboo)\
**Post date:** [September 2, 2015, 4:45am UTC](https://discuss.emberjs.com/t/failsafe-component-helper/8705/8 "2015-09-02T04:45:23Z")

</div>

Thanks, Mate. This is helpful.
