# Programmatically rendering ember components

**URL:** <https://discuss.emberjs.com/t/programmatically-rendering-ember-components/6986>\
**Category:** Uncategorized\
**Created:** [December 26, 2014, 3:14pm UTC](https://discuss.emberjs.com/t/programmatically-rendering-ember-components/6986 "2014-12-26T15:14:58Z")\
**Posts on this page:** 18\
**Page:** 1

<div class="post-metadata">

**Author:** ![green\_arrow](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/green_arrow/32/9383_2.png) [@green\_arrow](https://discuss.emberjs.com/u/green_arrow)\
**Post date:** [December 26, 2014, 3:14pm UTC](https://discuss.emberjs.com/t/programmatically-rendering-ember-components/6986/1 "2014-12-26T15:14:58Z")

</div>

There are quite a few posts out there about this topic. [I wrote one myself a while back.](http://blog.greenarrow.me/dynamically-rendering-ember-components/)

There is also [another topic on this forum](http://discuss.emberjs.com/t/how-to-dynamically-load-ember-components-by-name-in-a-template/6312) that goes over this topic as well. The solution in that thread was to do the following:

```auto
import Ember from 'ember';

function renderComponent(componentPath, options) {
  var helper = Ember.Handlebars.resolveHelper(options.data.view.container, componentPath);
  return helper.call(this, options);
}

export {
  renderComponent
};
export default Ember.Handlebars.makeBoundHelper(renderComponent);

```

The issue with this is that `options.data.view.container` is no longer available as of Ember 1.9 (possibly 1.8, I haven’t checked that though). As a temporary stop-gap, you can avoid creating a helper via `makeBoundHelper` and do something like this:

```auto
export default function(componentBinding, options) {  
    var componentPath = Ember.Handlebars.get(this, componentBinding, options),
        helper = Ember.Handlebars.resolveHelper(options.data.view.container, componentPath);

    return helper.call(this, options);
});

```

Here we’re simply accounting for the fact that our first argument is no longer a bound value, but the binding path. To get the actual value, we must call `Ember.Handlebars.get` (`makeBoundHelper` takes care of this for us, hence the name `bound`.). However, `Ember.Handlebars.get` is deprecated in favor of `makeBoundHelper`, so this is not an ideal solution.

The ideal solution, in my opinion, is to figure out where `options.data.view.container` went when using `makeBoundHelper`. Does anyone have any insight into this issue?

---

<div class="post-metadata">

**Author:** ![mitchlloyd](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/mitchlloyd/32/14502_2.png) [@mitchlloyd](https://discuss.emberjs.com/u/mitchlloyd)\
**Post date:** [December 27, 2014, 5:14pm UTC](https://discuss.emberjs.com/t/programmatically-rendering-ember-components/6986/2 "2014-12-27T17:14:18Z")

</div>

It seems that the container is available in the context of the helper function:

```auto
import Ember from 'ember';

function renderComponent(componentPath, options) {
  var helper = Ember.Handlebars.resolveHelper(this.container, componentPath);
  return helper.call(this, options);
}

export {
  renderComponent
};
export default Ember.Handlebars.makeBoundHelper(renderComponent);

```

However, when I run this code I get a downstream error because the options don’t contain a view. I think losing `options.data.view.container` is just the tip of the iceberg here. It looks like the streams work has changed a lot of how the internal rendering works.

The only way something like this is going to continue working across versions of ember is if someone creates an official public helper for it. I found [this github issue that you might want to resurrect](https://github.com/emberjs/ember.js/issues/5007).

cc @mmun @rwjblue

---

<div class="post-metadata">

**Author:** ![green\_arrow](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/green_arrow/32/9383_2.png) [@green\_arrow](https://discuss.emberjs.com/u/green_arrow)\
**Post date:** [December 27, 2014, 6:18pm UTC](https://discuss.emberjs.com/t/programmatically-rendering-ember-components/6986/3 "2014-12-27T18:18:34Z")

</div>

Thanks @mitchlloyd, I’ve commented on that github issue. We’ll see where it goes from here.

I don’t know exactly how I feel about an official public helper for this. Sometimes, there are things I like to do in the helper that deviate from the standard “take this bound value and render a component based on it.”. I guess I could always take that additional logic and put it into a different helper that then calls into the official public helper, but I don’t really like how that feels.

---

<div class="post-metadata">

**Author:** ![samselikoff](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/samselikoff/32/16581_2.png) [@samselikoff](https://discuss.emberjs.com/u/samselikoff)\
**Post date:** [December 27, 2014, 8:37pm UTC](https://discuss.emberjs.com/t/programmatically-rendering-ember-components/6986/4 "2014-12-27T20:37:04Z")

</div>

I don’t know a ton about this issue but I have used [ember-dynamic-component](https://github.com/minutebase/ember-dynamic-component) before. Just wanted to make sure you’ve seen it.

---

<div class="post-metadata">

**Author:** ![green\_arrow](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/green_arrow/32/9383_2.png) [@green\_arrow](https://discuss.emberjs.com/u/green_arrow)\
**Post date:** [December 27, 2014, 9:04pm UTC](https://discuss.emberjs.com/t/programmatically-rendering-ember-components/6986/5 "2014-12-27T21:04:06Z")

</div>

I’ll be posting this on that Github issue, but it looks like it would be fairly simple to add a built-in component that does this. Following is the code I placed in `ember-handlebars/lib/helpers/component.js`:

```auto
import Ember from "ember-metal/core"; // Ember.assert
import lookupHelper from "ember-htmlbars/system/lookup-helper";

/**
 @module ember
 @submodule ember-htmlbars
 */

/**
 @method component
 @for Ember.Handlebars.helpers
 @param {String} componentName the name of the component to render
 */
export function componentHelper(params, hash, options, env) {
  Ember.assert('You can only one argument to the `component` helper, which should be ' +
               'a bound property whose value is the component to render.', params.length === 1);

  var helper = lookupHelper('loading-animation', env.data.view, env);
  return helper.helperFunction.call(this, [], hash, options, env);
}

```

I did a quick test in my application and it seemed to work correctly.

---

<div class="post-metadata">

**Author:** ![green\_arrow](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/green_arrow/32/9383_2.png) [@green\_arrow](https://discuss.emberjs.com/u/green_arrow)\
**Post date:** [December 28, 2014, 10:00pm UTC](https://discuss.emberjs.com/t/programmatically-rendering-ember-components/6986/6 "2014-12-28T22:00:26Z")

</div>

It looks like [the github issue](https://github.com/emberjs/ember.js/issues/5007) that @mitchlloyd mentioned is getting some attention and will be worked on in the near future.

@samselikoff - I am currently using the add on you suggested in the interim. Thanks for the suggestion!

---

<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:** [January 3, 2015, 3:01pm UTC](https://discuss.emberjs.com/t/programmatically-rendering-ember-components/6986/7 "2015-01-03T15:01:19Z")

</div>

Luke Melia’s `{{component}}` helper patch has landed on master.

[https://github.com/emberjs/ember.js/pull/10093](https://github.com/emberjs/ember.js/pull/10093)

---

<div class="post-metadata">

**Author:** ![jeremytm](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/jeremytm/32/10600_2.png) [@jeremytm](https://discuss.emberjs.com/u/jeremytm)\
**Post date:** [July 9, 2015, 4:27am UTC](https://discuss.emberjs.com/t/programmatically-rendering-ember-components/6986/8 "2015-07-09T04:27:56Z")

</div>

Sorry to revive this, but I’ve been looking around for a while with no luck.

How do we then use this to actually render a component **programatically** like the topic title suggests? With JS only?

I know how to add a component using the helper `{{component componentName}}`, but I don’t have the luxury of doing this in a template with what I’m working on. I’m creating an easy to use modal library where I can show a variety of modals from anywhere in the app.

I have a bunch of modals as components. But obviously I don’t want to go to each template and add all modal components in a hidden state, then just show each one as needed.

---

<div class="post-metadata">

**Author:** ![CaC](https://avatars.discourse-cdn.com/v4/letter/c/53a042/32.png) [@CaC](https://discuss.emberjs.com/u/CaC)\
**Post date:** [July 9, 2015, 12:25pm UTC](https://discuss.emberjs.com/t/programmatically-rendering-ember-components/6986/9 "2015-07-09T12:25:41Z")

</div>

@amk showed me a solid implementation for this:

> **[JS Bin](http://jsbin.com/hahohi/1/edit?html,js,output)**
>
> A live pastebin for HTML, CSS & JavaScript and a range of processors, including SCSS, CoffeeScript, Jade and more...

---

<div class="post-metadata">

**Author:** ![amk](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/amk/32/9116_2.png) [@amk](https://discuss.emberjs.com/u/amk)\
**Post date:** [July 9, 2015, 12:40pm UTC](https://discuss.emberjs.com/t/programmatically-rendering-ember-components/6986/10 "2015-07-09T12:40:15Z")

</div>

I think this has become an issue now that {{view}} is going away. [https://github.com/emberjs/ember.js/issues/11377#issuecomment-112364925](https://github.com/emberjs/ember.js/issues/11377#issuecomment-112364925)

Edit: @CaC That was a while ago… containerView probably won’t be around for much longer IMO

---

<div class="post-metadata">

**Author:** ![workmanw](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/workmanw/32/14929_2.png) [@workmanw](https://discuss.emberjs.com/u/workmanw)\
**Post date:** [July 9, 2015, 3:30pm UTC](https://discuss.emberjs.com/t/programmatically-rendering-ember-components/6986/11 "2015-07-09T15:30:39Z")

</div>

I am wrestling with this exact same problem. I currently use the pattern showed by JSBin linked by @CaC. However Ember.ContainerView is deprecated and will be removed.

So I looked around and found both the issue @amk linked and a comment where @ef4 had suggested to use `{{each}}` and `{{component}}` as a replacement for `Ember.ContainerView` on the [1.13 release blog post](http://emberjs.com/blog/2015/06/12/ember-1-13-0-released.html#comment-2079491525). At first that seemed to cover the use case, but the challenge is there is no real easy way to dynamically populate different `attrs` when using the `{{component}}` helper. Every single component class in the list would have to have the same attrs.

Example:

```auto
{{#each myComponentModals as |componentDetails|}}
  {{component componentDetails.name value=componentDetails.value checked=componentDetails.checked}}
{{/each}}

```

I think this pattern falls short of my needs currently. I don’t think it’s a fringe scenario for people to have dynamic components like this. Modals, dashboard widgets, reporting, customizable forms are all relatively common use cases IMHO.

Any advice would be greatly appreciated.

---

<div class="post-metadata">

**Author:** ![amk](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/amk/32/9116_2.png) [@amk](https://discuss.emberjs.com/u/amk)\
**Post date:** [July 9, 2015, 3:42pm UTC](https://discuss.emberjs.com/t/programmatically-rendering-ember-components/6986/12 "2015-07-09T15:42:45Z")

</div>

@workmanw Yeah, that’s the crux of it. Worth filing an issue?

I did read somewhere about a new syntax for the {{component}} helper to do just that, but struggling to find it.

---

<div class="post-metadata">

**Author:** ![CaC](https://avatars.discourse-cdn.com/v4/letter/c/53a042/32.png) [@CaC](https://discuss.emberjs.com/u/CaC)\
**Post date:** [July 9, 2015, 3:54pm UTC](https://discuss.emberjs.com/t/programmatically-rendering-ember-components/6986/13 "2015-07-09T15:54:47Z")

</div>

I think the best and simplest way would be:

**controller.js**

```
import Component from '../components/my-component';
comp: function(){ // because 'component' is a taken keyword
  return Component.create({
    some: 'properties'
  })
}

```

**template.hbs**

```
{{comp}}

```

I don’t know which problems would it cause, or against which Ember dogma does it go.

Question: How would it be possible to solve? I guess there is a template parser, which identify mustaches, and if it a keyword, then it process it, if it a property, then prints it. It could check if it an `instaceof` a component.

I started a naive workaround but i got stuck: [JS Bin - Collaborative JavaScript Debugging](http://emberjs.jsbin.com/lirawekapu/1/edit?html,js,output)

Ok, so whats going on here?

On initialization i register a keyword `component-2`

```
Ember.Application.initializer({
  name: 'register-keywords',
  initialize: function(){
    var registerKeyword = Ember.__loader.require("emberhtmlbars/keywords").registerKeyword;
    registerKeyword("component-2", component);
  }
});

```

`component-2` takes two parameters, the first is the name of the component, 2nd is a hash of properties.

**controller.js**

```
obj: {foo: 'bar', baz: false}

```

**template.hbs**

{{component-2 ‘my-foo’ obj}}

is equivalent to

**template.hbs**

{{‘my-foo’ foo=“bar” baz=false}}

But it wont update if I change `obj`. Although `rerender` runs and `hash` has the new value. Anyway I like my first proposal better, but maybe I gave some idea how it should work.

---

<div class="post-metadata">

**Author:** ![workmanw](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/workmanw/32/14929_2.png) [@workmanw](https://discuss.emberjs.com/u/workmanw)\
**Post date:** [July 9, 2015, 9:48pm UTC](https://discuss.emberjs.com/t/programmatically-rendering-ember-components/6986/14 "2015-07-09T21:48:33Z")

</div>

@amk I’m not sure if it qualifies as opening an issue. I feel as though they would direct me to stackoverflow or here to ask my question.

I was really hoping to maybe see core team member weigh in here, but I know they’re very busy.

@CaC I worry about the later solution being too brittle. Ultimately feels like Ember should have a native way to do this. ☹

---

<div class="post-metadata">

**Author:** ![workmanw](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/workmanw/32/14929_2.png) [@workmanw](https://discuss.emberjs.com/u/workmanw)\
**Post date:** [July 10, 2015, 10:21pm UTC](https://discuss.emberjs.com/t/programmatically-rendering-ember-components/6986/15 "2015-07-10T22:21:22Z")

</div>

@CaC @amk This looks really promising: [Splat operator · Issue #1050 · handlebars-lang/handlebars.js · GitHub](https://github.com/wycats/handlebars.js/issues/1050) .

---

<div class="post-metadata">

**Author:** ![CaC](https://avatars.discourse-cdn.com/v4/letter/c/53a042/32.png) [@CaC](https://discuss.emberjs.com/u/CaC)\
**Post date:** [July 11, 2015, 2:47pm UTC](https://discuss.emberjs.com/t/programmatically-rendering-ember-components/6986/16 "2015-07-11T14:47:00Z")

</div>

Great found @workmanw! This looks really great, indeed. I hope it will be implemented soon!

---

<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:** [July 13, 2015, 6:53pm UTC](https://discuss.emberjs.com/t/programmatically-rendering-ember-components/6986/17 "2015-07-13T18:53:14Z")

</div>

> [@jeremytm](#):
>
> but I don’t have the luxury of doing this in a template

To be absolutely clear: the only public API for instantiating components is from within templates. This is intentional.

I realize that experienced Ember devs are accustomed to the old view hierarchy model, and so they tend to reach for that when they hit a blocker. But that model doesn’t actually exist anymore, and in the places where it still works, you’re actually using backward-compatibility shims provided by Glimmer that incur performance cost.

If you find something that’s not possible to wire up correctly in a template, that’s a bug we need to solve. It sounds like the only gap mentioned in this thread so far is the need for [a splat operator](https://github.com/wycats/handlebars.js/issues/1050), which is something I want too, and I’m sure we can add without much difficulty. Another relevant discussion is [the contextual component lookup RFC](https://github.com/emberjs/rfcs/pull/64).

Liquid Fire has the same issue with modals that you’re describing, but I’m convinced that’s actually because it’s not a great API in the first place. Any time people are trying to describe how to render a component, but they’re not doing so from a template, you’re forced to reimplement a bunch of nice things that templates do automatically. My plan for liquid-fire is to deprecate the existing modals and instead make it easy to compose liquid-fire plus ember-wormhole, so that addons like ember-modal-dialog can easily animate.

---

<div class="post-metadata">

**Author:** ![jeremytm](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/jeremytm/32/10600_2.png) [@jeremytm](https://discuss.emberjs.com/u/jeremytm)\
**Post date:** [July 13, 2015, 9:58pm UTC](https://discuss.emberjs.com/t/programmatically-rendering-ember-components/6986/18 "2015-07-13T21:58:54Z")

</div>

@ef4 and everyone. Thanks for your help.

I see now it’s more complex than I assumed it would be with how great the rest of Ember is.

For now I’m just loading a component in the application template, and then am using a service and event bus to show and hide things from there.
