Reputation: 81
I'm using a web component in my angular app. I am using angular attribute bindings to dynamically fill my web component: https://angular.io/guide/attribute-binding
When I hardcode the values for my web component attributes, it works fine. However, when I dynamically bind the attributes, I run into issues.
What seems to be happening is the template loads, then the authVariable is set to the auth-token attribute once the component loads. The web component I am using throws an error when the template loads before the component loads. When the template is then filled with the authVariable, the web component doesn't recover from the error state.
The component I am using does have a default value for authVariable (I'm not doing an async call to get a value for authVariable).
My question is: What is the easiest way to have angular only load a filled version of the template?
This works fine
<web-component
auth-token="<AUTH_TOKEN>"
>
</web-component>
This doesn't work
<web-component
[attr.auth-token]="authVariable"
>
</web-component>
Upvotes: 1
Views: 472
Reputation: 1735
This is probably a bug with the web component itself. It should be able to detect changes to attributes with the attributeChangedCallback
method. However, if you need to work around this issue, you would need to use outerHTML
to insert the markup yourself to be evaluated all at once instead of when Angular feels like setting the attributes. Because you'll need to use bypassSecurityTrustHtml
to get Angular to parse the non-trivial markup, you need to be confident that the template string you pass in has no security flaws (like interpolating user input), otherwise you'd be opening yourself up to XSS attacks.
// my.component.ts
import {DomSanitizer, SafeHtml} from '@angular/platform-browser';
@Component({…})
class MyComponent {
private readonly authVariable = '…';
protected readonly webComponent: SafeHtml;
constructor(private readonly sanitized: DomSanitizer) {
this.webComponent = this.sanitized.bypassSecurityTrustHtml(`
<web-component auth-token="${this.authVariable}">
</web-component>
`);
}
}
<!-- my.component.html -->
<template [outerHTML]="webComponent"></template>
Upvotes: 1