'Angular Elements - cannot pass variable to @Input property of my Elements Tag

I need some assistance here, I am unable to pass a variable to the @Input variable of my Elements tag. If I hard code a caller-id = "123456" inside the tag it works with no issues; however if I try and pass the caller id from the Angular component as a variable it does not recognize it. I am basically trying to retrieve the userId of the component and pass it to the elements app to do what it needs to do with the userId. Any help would be appreciated, thanks.

Angular Elements App .ts

export class AppComponent implements AfterContentInit {


 @Input() userId: string = "";
 @Input() userId2: string = "";


ngAfterContentInit() {
console.log(this.userId);
console.log(this.userId2);
}}

app.module.ts of Angular Elements App

import { BrowserModule } from '@angular/platform-browser';
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import {createCustomElement} from '@angular/elements';
import { Injector } from '@angular/core';


@NgModule({
 declarations: [
 AppComponent
 ],
 imports: [
  BrowserModule
  ],
  providers: [],
 entryComponents: [AppComponent],
 schemas: [CUSTOM_ELEMENTS_SCHEMA],
 bootstrap: [AppComponent]
 })
 export class AppModule { 
 constructor(injector: Injector) {
  const custom = createCustomElement(AppComponent, {injector});
  customElements.define('elements-app', custom)
 }

 ngDoBootstrap() {

 }
 }

Current Angular Component that is implementing the angular elements tag from .js

.ts file of component implementing the Elements App

 constructor() {
 this.userId = "123456"
 }

HTML file of component implement the Elements app

*does not work*- <elements-app user-id=userId></elements-app
*works*- <elements-app user-id="123456"></elements-app

app.module.ts of the app consuming the angular elements .js file tag

 @NgModule({
  declarations: [
   AppComponent
 ],
 imports: [
 BrowserModule,
 AppRoutingModule,
 BrowserAnimationsModule,
 HttpClientModule
 ],
 providers: [HttpClientModule, HttpClient],
 schemas: [CUSTOM_ELEMENTS_SCHEMA],
 bootstrap: [AppComponent]
  })
  export class AppModule { }


Solution 1:[1]

Have you tried: <elements-app [attr.caller-id]="caller_id"></elements-app> ?

Solution 2:[2]

I tried all the solutions suggested in this thread but nothing worked out. Then I understood that we're trying to pass a dynamic variable to a simple html(non-angular) element. So I tried DOM manipulation using the ElementRef with ViewChild and updated the attribute of custom element.

You can update your html to

<elements-app #customEl></elements-app>

In script add this

@ViewChild('customEl') customElement: ElementRef;

ngAfterViewInit():void {
  this.customElement.nativeElement.setAttribute('user-id', userId);
}

This worked for me and if it does not for you, it may be due to the custom element's js file which is already referred. Try removing the static script tag reference and load the js file dynamically after updating the element. You can refer to this article for loading js https://jsonworld.com/blog/how-to-add-script-dynamically-in-angular-application

Solution 3:[3]

Not sure if it is best approach but it worked fo me: I solve this creating the tag in a variable, then use it as innerHtml for a DIV. (I had to sanitize the value):

import DomSanitizer:

import { DomSanitizer } from '@angular/platform-browser';

then add it to the constructor:

constructor(private _sanitizer: DomSanitizer) {}

then create de innerHTML variable:

  ngOnInit(): void {
    this.innerHTML = `<elements-app caller_id=${this.caller_id}></elements-app>`;
    this.innerHTML = this._sanitizer.bypassSecurityTrustHtml(this.innerHTML);
  }

and finally on the template:

<div [innerHTML]="innerHTML"></div>

Solution 4:[4]

You need quotes " around the caller_id variable or it won't work. Also a box binding around caller-id

Change <elements-app caller-id=caller_id></elements-app>

To <elements-app [caller-id]="caller_id"></elements-app>

Check this out for more info https://angular.io/guide/component-interaction#intercept-input-property-changes-with-a-setter

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Akk3d1s
Solution 2 Sai Prasad Ragula
Solution 3 Cristian Sepulveda
Solution 4 James