0

I have a project generated with @angular/cli v7.0.3.

I've pushed a small demo application here: https://github.com/collinstevens/web-component-sender

I have added @angular/elements and the @webcomponents/webcomponentsjs polyfill.

I have a basic Angular component, AppComponent, and a web component built using @angular/element defined in the AppModule constructor using ReceiverComponent as the Angular component and web-receiver as the web component tag.

I expect when I type into the AppComponent it will update the AppComponent and the ReceiverComponent with the updated value.

Currently, only the AppComponent is receiving the updated value, while the ReceiverComponent will display only the initial value set in the AppComponent.

Given https://angular.io/guide/elements#mapping, the myValue Input() on ReceiverComponent should be mapped as my-value.

AppComponent

export class AppComponent {
  value = '';
}

<div>
  <span>Angular Component Input:</span>
  <input [(ngModel)]="value">
</div>

<div>
  <span>Angular Component Span:</span>
  <span>{{value}}</span>
</div>

<div>
  <span>Web Component Span</span>
  <web-receiver [my-value]="value"></web-receiver>
</div>

ReceiverComponent

export class ReceiverComponent {
  @Input()
  myValue: string | undefined = undefined;
}

<span>{{myValue}}</span>

AppModule

@NgModule({
  imports: [BrowserModule, FormsModule],
  declarations: [AppComponent, ReceiverComponent],
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
  bootstrap: [AppComponent],
  entryComponents: [ReceiverComponent]
})
export class AppModule {
  constructor(private injector: Injector) {
    const senderElement = createCustomElement(ReceiverComponent, {
      injector: this.injector
    });
    customElements.define('web-receiver', senderElement);
  }
}
Collin Stevens
  • 737
  • 9
  • 19

1 Answers1

0

This does the job:

<web-receiver [myValue]="value"></web-receiver>

The reason is that Angular binds to (javascript) properties.

Manfred Steyer
  • 479
  • 3
  • 12
  • I think you have forgotten to add the code? I'm only seeing white space after your colon! – Collin Stevens Oct 26 '18 at 17:57
  • If I bind to that, I receive ExpressionChangedAfterItHasBeenCheckedError errors every time the value changes. According the @angular/elements documentation, it creates an attribute mapping for each Input(), in this case, my-value. Is this the intended behavior that mutating the attribute will not cause the Input() property to change? – Collin Stevens Oct 26 '18 at 19:38
  • Yes, Angular Elements give you both, Attributes and Properties. You could bind to the exposed attribute using [attr.my-value]="value". However, this does not make the error go away. – Manfred Steyer Oct 26 '18 at 23:30
  • Is there a way to do one way data binding to an angular element which passes data updates and also avoids errors? It seems as though this must be a common use case. – Collin Stevens Oct 27 '18 at 02:58