Programmatically generated html code not working. (click)= Pipe Filter Render Event Button

Is there a change that this get fixed soon?

Programmatically generated html code not working. (click)= event not get fired.

I managed to get the HTML code interpreted and does render a button, but the (click) does not get fired, so no action.

I also tried via Filter / Pipe but this also does not fires a click event.

image

HACK - Mix with JQuery also not working…
I managed to get a click event onclick with regular JQuery, but then I
can not - or don’t know how to call the “original” click event function
from within Ionic / TypeScript.

It’s hard to say much without seeing any code, but if you’re using innerHtml, directives aren’t going to work. You can try using DynamicComponentLoader, but I really would recommend trying to rethink the design so that it’s not needed.

1 Like

Yes, it’s innerHtml, coming from a JSON file. Ah, again, this DynamicComponentLoader thing… I always see this gets written down “as a solution”, but nobody seems to know how this works, etc. and it’s far too complicated.

I just read from a JSON file, and need to filter some thing, (12) for example, to make a button like so:

<button id="12" (click)="doAction('12');">12</button>

Can’t be that difficult? With Ionic 1 this was no problem by using just a filter. (Now it’s called a pipe I think.)

BTW: I will and have to stick with ionic 1 - without any new UI elements - just because of this simple things not working.

Any advice still welcome for Ionic 2. Ionic 1 was OK, but missing basic functionalities like search-bar, etc. Sharing, etc. only possible with external plugins. Why not create the basics first? Then move on to cool TypeScript? Now one can not switch to version 2 because it’s not working, Ionic 1 missing features only available in version 2. So I’m stuck in the middle getting nowhere… :frowning:

Angular1 had ng-bind-html and trustAsHtml. They were extremely difficult to use securely, and I think eventually you will come around to not missing them. I have. As for your situation, try something like this?

things: string[];

getThings(): void {
  this.http.get('/api/foo')
    .subscribe((rsp) => {
      let obj = rsp.json();
      this.things = this.massageJsonIntoArray(obj);
    });
}
<button *ngFor="#thing of things"
  [id]="thing" (click)="doAction(thing)">
{{thing}}
</button>

“extremely difficult to use securely” Really? I don’t think so. That’s the point where many API and UI framework developer get’s wrong. I can say that it is save. Why? Because I use only my local files as a source, not any remote url or remote location. So I know what data is there and what’s not.

I do have something like you example code.

How can this work? I do have simple text that needs to get formatted as HTML basically. So it’s more a HTML then a JSON.

So for example:

“Hello XY, I need (12) pizzas fast!”

Where
(12) would be translated / converted to a button, which should call a function with the argument 12.

Again, the data JSON file is only available in my domain, locally on the device. Not over internet. So I know what the contents of the JSON file is.

Put everything needed to render into the type of the object you’re looping over with *ngFor.

<div *ngFor="#order of orders">
  Hello {{order.name}}, I need <button (click)="placeOrder(order)">{{order.numPizzas}}</button> pizzas fast!
</div>

I have that. Does not work because i cant us fixed template as i said the buttons must get crested dynamically based on whats onside my jdon file.

Good luck then. I’ve tried to address every concrete feature you said you needed. Either rearchitect your design so you can do it with fixed templates (which I firmly believe is possible, despite your “can’t” and “must”), or go play with DynamicComponentLoader.

How? Do you have some simple working code? (Beta 5, and / or Beta 6)

DynamicComponentLoader : I seems to be not that simple as with pipes or filters.

I need a working solution. The input JSON is known, and never changes as long as the app is running.

One entry can look like:

JSON Entry A:
“Hello XY, I need (12) pizzas fast!”

JSON Entry B:
“Other text here, changes every entry (2) other text here for every entry different.”

Should translate to:

“Hello XY, I need <button with click 12 as arg> pizzas fast!”

“Other text here, changes every entry <button with click 2 as arg> other text here for every entry different.”

to call somehow a TypeScript function with the given arguments.

With pipes / filters it translates via innerHtml to a button, but the button does nothing.

You should be able to extend the following idiom to handle any number of potential styles, chosen by a discriminator field in the loop variable. If you prefer, turn each style into a custom component.

<template ngFor #order [ngForOf]="orders">
  <div [ngSwitch]="order.style">
    <template [ngSwitchWhen]="A">
      Hello {{order.name}}, I need <button (click)="placeOrder(order)">{{order.numPizzas}}</button> pizzas fast!
    </template>
    <template [ngSwitchWhen]="B">
      {{order.firstText}} <button (click)="placeOrder(order)">{{order.buttonText}}</button> {{order.secondText}}
    </template>
  </div>
</template>
1 Like

Hmm… there is no fixed style / template / pattern.

The only thing that is fixed is “(12)” which should be translated to a button, that’s all. All text except “(12)” or “(n)” (where n is any integer) should be translated to a button with a function call with argument.

So the text “surround” of the pattern “(n)” should be untouched.

More like a “stream” (strings, within JSON) of data, where a pattern “(n)” could be there or not.

I’m sorry, I’m going to have to stop at this point. You keep moving the goalposts, and I’m getting frustrated with it.

No, I just want to have a pattern (n) replaced with a button with a click, that’s all. It’s clear that the simple example with the Pizza order is just an example, not fixed text. There is no moving target here. Pipe / Filter worked with Ionic 1 but it does not work with Ionic 2.

So Ionic 2 is not useful for many apps at all if it can’t handle such a simple thing.

I think that the following suggestion is your best bet for Ionic 2:

This is the answer for Ionic 2 but of course it’s not the only option, i.e. you still could:

  1. Keep using Ionic 1, where as far as I understood everything works as expected.
  2. Propose a new feature for Ionic or Angular - if it’s useful it might be implemented.
  3. Implement the needed functionality yourself and create a PR for Ionic or Angular.

Both Ionic and Angular are open source projects, which means that if something is missing, doesn’t work as expected or is not suited for a particular use case then it’s up to the community to help addressing it.

Ionic 2 certainly can’t handle every possible use case (especially when it’s still in beta). Some people will find it useful while others won’t - just like with every other framework/tool. However since this is such a simple thing I guess that it won’t be difficult for you to implement it yourself.

Hopefully you’ll be able to find the best option for your case.