Function got undefined on onclick()


#1

I know this same question has been asked many times before, but no solution worked for me. And I already have spent many hours on it.

In my case I am simply replacing a text with with an html element and on onclick event I want to call an event or a function defined in the same class.

var linkToReplace = '<a onclick="this.events.publish(\'issue:display\')">'+issueKey+'</a>';

Error is given below:

Uncaught TypeError: Cannot read property 'publish' of undefined.

it works for "alert(\'hello\')", but all other functions got undefined.

Thanks in advance!


#2

Put that this.events.publish inside a function in your ts. Then call that function in your onclick.


#3

Yes, I tried it just now. Now the text appears as a link but when click on it, nothing happen. No alert and nothing in console.


#4

Have you tried this?


#5

Yes, I tried it just now. Now the text appears as a link but when click on it, nothing happen. No alert and nothing in console.


#6

Try it:


<a (click)="displayIssue($event)">'+issueKey+'</a>

public displayIssue(event) {
   console.log('------>', event);
}


#7

I believe that the problem is with escaping “” characters. As if I print it in console, it displays:

'<a (click)=\"displayIssue()\">ABD-555</a>'

and when I click on link, nothing happens. I am trying to escape it correctly but no luck.


#8

I strongly suggest not mixing templates and component code. Even if you get it to work in development mode, it will break in mysterious ways with the ahead-of-time compiler. Keep template code in templates.


#9

I understand but I am in a situation that I need to replace sequence of characters if found in text with clickable links. I am still not able find a better solution for this. :confused: :disappointed:


#10

There is always another way. You could parse these “sequences of characters” into a heterogeneous array of objects, loop across this array with an ngFor and render links when the object is a link type.

I guess other peoples’ experiences may vary, but every single time I have started out doing anything with HTML inside an Angular 2 component, I eventually gave up and did literally anything to avoid doing so. The framework really really does not want you to be doing this.


#11

You need to use ViewContainerRe.createEmbeddedView. Otherwise angular won’t add bindings to dynamically inserted HTML.

Also this inside of onclick refers to HTML element in case of plain Dom events. That’s why it doesn’t work

Check the source of ngIf to get an idea of how this can be done.

Another approach is to Use event delegation + event target and attrs on a tags

'<a data-event="issue:display">' + issueType + '</a>'

Then in component

@HostListener('click', ['$event.target'])
publishEvent(target) {
  this.events.publish(target.getAttribute("data-event")
}

#12

I just had to take a moment from banging my head against various solid objects to second this statement. It is so obtusely difficult to work with anything beyond basic html content outside of a template in angular2. Very frustrating if you’re trying to keep your data uncoupled from the view components.