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);
  }
}

1 Answer 1

0

This does the job:

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

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

Sign up to request clarification or add additional context in comments.

4 Comments

I think you have forgotten to add the code? I'm only seeing white space after your colon!
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?
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.
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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.