I’m experimenting with Angular Elements and trying to update an input property programmatically, not by writing it in HTML like <app-foo name="...">.
Here’s a minimal example:
import {
Component,
Input,
Injector,
inject,
NO_ERRORS_SCHEMA,
} from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import { createCustomElement } from '@angular/elements';
@Component({
selector: 'foo',
template: `foo works! {{ name }}`,
})
export class Foo {
@Input() name = '';
}
@Component({
selector: 'app-root',
template: `
<h1>Hello from {{ name }}!</h1>
<app-foo></app-foo>
`,
schemas: [NO_ERRORS_SCHEMA],
})
export class App {
name = 'Angular';
injector = inject(Injector);
constructor() {
const el = createCustomElement(Foo, { injector: this.injector });
customElements.define('app-foo', el);
const e = document.querySelector('app-foo') as any;
e.name = 'bla'; // property
e.setAttribute('name', 'bla'); // attribute
}
}
bootstrapApplication(App);
I expect the <app-foo> element to display foo works! bla, but it still shows the default foo works!.
I’ve tried both:
e.name = 'bla';
e.setAttribute('name', 'bla');
but neither triggers Angular’s change detection.
Question:
How can I properly set an @Input() property on an Angular custom element created with @angular/elements so the component updates its template when done programmatically?