Generate html components dynamically

Hi,

Is there a way I can generate a component dynamically?
For example. I have a ion-radio component in string like this in my class:
this.radioContent = '<ion-radio value="rarely" (click)="broadcastInputChange($event)">Radio Contnet</ion-radio>';

Now I want to use it in my template like this,

{{radioContent}}

It does generate normal html components like div, span, li etc but not components like ion-radio, ion-input etc.
Is there a work around for that?

IMHO this is a bad idea. If you can describe what you’re trying to achieve in broader terms, maybe we can suggest alternatives.

The strategy you describe is not compatible with ahead-of-time compiling. You may be used to thinking about programming for one computer in a lab, and in a context like that your approach would make sense. But hybrid development for the browser is different.

Well the basic concept is that the api is returning me complete template in html form which has ionic components as well. I need to render this template inside my page template. Is there a way to do that?

I would rethink the design here. Have the API return some sort of intermediate format, not HTML.

Yeah this was my suggestion to my employer. Lets see what he thinks about it.

Meanwhile, could there be a solution for the scenario i have?

1 Like

I don’t understand what this means. Are you saying the api relies on the user to specify the user’s platform, so the server correctly serves an Android implementation to user X and an iOS implementation to user Y?

API does not rely on user’s platform.

The scenario is that the API returns we an html in response to POST method. I want this html to be used in my ionic template as innerHtml of div. It works fine for normal html tags like p, div, li, span etc. But if the html response which I receive from API has ionic components like ion-radio, ion-input etc then they don’t get rendered inside innerHtml.

So my question is that is there a way I can render an ionic component using innerHtml inside a template object?

My answer is that it will be much better off for you in the long run if you stop attempting to find such a way and simply tell everybody asking you for one that “no, it is not possible”.

Those aren’t html components. Inspect an Ionic page in the browser and you’ll see what I mean. They get translated into platform-specific HTML, a bit like a polyfill. If you want to use this particular strategy, you shouldn’t use a hybrid development network. Better to use a framework that is just for HTML development.

A smaller issue you’d have to deal with is that Angular sanitizes innerHTML by default. But it sounds as though whoever is telling you to do things this particular way does not understand what an Ionic component actually is. It isn’t an HTML tag – closer to an equivalence class of HTML structures.

As others have clarified, Ionic/Angular tags don’t represent HTML elements directly, they have to be compiled to get the actual equivalent code in HTML. So, what you are trying to do is representing the Ionic tags in plain string and thinking that they’ll be automatically changed into valid HTML for you to inject into the DOM, that’s not going to happen just like that.

If you anyhow need to do this though, then here is a starting point:

I understand being in the position of being told to just make it work. That being said, please do not go down this road. Even if you manage to hack something together, it is subverting the spirit of the framework, it needlessly opens you up to security concerns, it makes your app impossible to test, and it opens you up to numerous frustrating differences between development and production mode.

2 Likes

Hey @rapropos, I totally agree to what you said there. At the same time though, I am thinking shouldn’t there be a formal provision to do this properly?

I went around and around on this when porting an Angular1 application that is a BBS using Markdown. Initially I was frustrated with the Angular team’s decision to eliminate this functionality, and eventually I decided that they understood their framework better than I did. So I went with this strategy, and I still think it’s the best approach for situations like this.

PS: stupid discourse won’t let me edit that post now, but <template> needs to be changed to <ng-template> going forward.

1 Like

Thanks for the explanation and the reference. Although I am not in a position to understand everything you’ve said immediately, I get that your approach is a better one. I think the OP should follow it, thanks!

For FMTEYEWTK on this topic, you can start reading angular #7596.

1 Like

Hi, employer here to give a bit more background.

So I definitely get why this appears to be a bad idea, but I’d like to add the reason for the requirement and a couple of points.

I appreciate the responses which suggest some sort of builder of templates based on structural data returned from the API. However the issue that we’ll be facing is that our clients, those who will be using the app, will not be able to update the app itself that frequently. It will be in a private repo and there’s no guarantee that they’ll be using the latest version. The only updates they’ll be constantly receiving is from the API.

The API does not return pre-compiled HTML but rather dynamically generated ionic templates meant for consumption/rendering by one of the components.

The templates can be very customized and so having the app dynamically build the templates based on structural data would only work if the app was updated frequently, because the definitions of how to build the templates would be built in to the app.

Rather, we’d much prefer that the app – in it’s 1.0 state – is capable of being fed template strings right from the API because that ensures that any non-standard templates can be generated on the server via the API rather than in the app.

I had a beta working in Ionic2/Angular2 (early RC) with ng-dynamic-component using this strategy, and @casperkotwal has since updated the codebase to the latest versions, but perhaps something has changed in the code which makes this strategy no longer possible (or possibly still a bad strategy).

Thanks for all of the help!

The bottom line is that ngc: the Ahead-of-Time compiler that provides much better (and for many apps, the only acceptable level of) performance needs access to all the templates at build time. I think this is a wall that there is simply no way around. It turns those components into JavaScript classes that are bundled into the app binary.