I have a native webcomponent with a callback function 'myCallback'.
<script>
class MyComponent extends HTMLElement {
constructor() {
super();
this.myCallback = this.getAttribute("my-callback");
}
connectedCallback() {
this.innerHTML = "MyComponent";
const me = this;
setTimeout(function () {
const cb = me.myCallback;
if (typeof cb === "string") {
new Function(cb).call(window);
} else if (typeof cb === "function") {
cb.call(window);
} else {
console.log("not a function: " + cb);
}
}, 1000);
}
}
customElements.define("my-component", MyComponent);
</script>
I want to use this webcomponent in Angular and assign a callback to it but it doesn't seem to work. This is what I have tried so far:
<my-component my-callback="angularCallback()"></my-component>
<my-component my-callback="{{angularCallback}}"></my-component>
<my-component [my-callback]="angularCallback"></my-component>
<my-component [my-callback]="angularCallback()"></my-component>
<my-component (my-callback)="angularCallback()"></my-component>
The first line above throws the error "angularCallback is not a function" because it is not defined in the window, but in Angular. The other lines are never called and do not throw any error.
As a simple test I tried the following and it works fine:
<my-component my-callback="console.log('test-callback');"></my-component>
Is there a way to assign the callback in Angular via the template?
Update with solution
The mistake that I made was that I tried [my-callback]
instead of [myCallback]
So the solution is the following:
<my-component [myCallback]="angularCallback"></my-component>
Attributes are passed down to a custom element as a string. When passing a function, it will be easier to pass it as a property on the custom element.
You could pass the property using the []
syntax in Angular.
<my-component [mycallback]="callbackMethod"></my-component>
The callbackMethod being a simple function in the ts code.
callbackMethod = () => console.log('callback method called');
Then in the custom web component, you can directly access the property value.
setTimeout(function () {
// directly access the callback property on the component
const cb = this.mycallback;
if (typeof cb === "string") {
new Function(cb).call(window);
} else if (typeof cb === "function") {
cb.call(window);
} else {
console.log("not a function: " + cb);
}
}, 1000);
I've created a StackBlitz example to illustrate this.