Button Click on Dynamically Loaded HTML Text

I am upgrading a site from javascript and jquery to Angular 7.

The site makes API calls to a server to deliver the HTML code.

What I am running into is that the code that comes from the server does not work.  For example, here is a test example from my html component that shows the problem.

<div [innerHTML]="pageInfo.text | safeHtml"></div>
<p><button class="btn btn-default" (click)="btnclck('btngo')">Test</button></p>

Open in new window


The first line is loaded in on initiation when the site loads and then changes when you move to a new page.
The second is a test line that I placed in there just to illustrate my problem.

The second line works exactly as it is supposed to.

But if the same button code comes in from an api read from the database, it doesn't work.

If you look at the code in the code inspector, you will see that the Angular coding has been applied to the second, but not to the first.

Angular Button Description
My assumption is that because this dynamic text is loaded after the rest of the site, the angular coding is not applied to the button tag and as such, the onclick doesn't work.

How do I get around this?  

The code has to come dynamically from a database.
Paul KonstanskiProject SpecialistAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Paul KonstanskiProject SpecialistAuthor Commented:
It is related in that it is passing of the dynamic HTML text but the issue is with how TypeScript formats things.  

If I send what looks like an Angular formatted button click dynamically, and then inspect it with the code inspector, it show it as:

<p><button class="btn btn-default" (click)="btnclck('btngo')">Continue</button></p>

But if that same button click line was placed in the "Component" and not dynamically loaded, upon inspection it looks like this:

<p><button class="btn btn-default" _ngcontent-c11="">Continue</button></p> and it is labeled as an "Event".  See this image.

So for HTML that is in the component at the time the page loads, it converts it to typescript.

So I tried another experiment and I passed the exact same text as what the Typescript rendered text looks like (e.g. the _ngcontent-c11) and when I click on the two buttons, the one that is in the Component works fine.  But the dynamically read in text does not.  You can see from this "inspection" image that only the component button is labeled "Event" (as indicated by the blue button).
Inspector with Event HighlightedSo what I can't figure out is how to get a button press (or a submit button for that matter or any of the interactive elements of a form) to work when they are dynamically loaded.  It seems that only text that is on the page prior to loading works.

Is there a way around this?
Julian HansenCommented:
The problem is that Angular2+ only does compiling on components - not on partial updates. You would need to wrap this in a component and then re-compile the component.

I can't give you a full solution now - but do some checking on recompiling components and you should find some code on how to do that. If you don't come right post back here and I will pick it up again.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Get Blueprints for Increased Customer Retention

The IT Service Excellence Tool Kit has best practices to keep your clients happy and business booming. Inside, you’ll find everything you need to increase client satisfaction and retention, become more competitive, and increase your overall success.

Paul KonstanskiProject SpecialistAuthor Commented:
I haven't had a chance to test implementing the content of this article, but is this or something similar to it the process for recompiling components?

Dynamically Loading Components Article

If this is the right track, I'll work at getting something like this working.

Thanks.
Julian HansenCommented:
Yes that looks like it is in the ballpark.
Paul KonstanskiProject SpecialistAuthor Commented:
Here is the article that gave me what I needed. This is a GREAT explanation that walks you through step by step. They had this loading into the app.component but I was able to easily move it to my home component and it works great.  

Dynamic Form, Configurable Fields

They also have a stack blitz site with this in action.

Then once I got it working for when the site first loads, I then had to figure out how to get it to advance to the next dynamically loaded page. I did that by using this sequence.

  gotoPage(pgref: string) {
    let gopage = String('home/'+pgref);
    this.router.navigateByUrl('/home', {skipLocationChange: true}).then(()=>
    this.router.navigate([gopage])); 
  }

Open in new window


It is great to see it coming together.
Paul KonstanskiProject SpecialistAuthor Commented:
Thanks again for the help.
Julian HansenCommented:
You are welcome.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
JavaScript

From novice to tech pro — start learning today.