1

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 { }
Rob DePietro
  • 284
  • 2
  • 8
  • 23

4 Answers4

0

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

Akk3d1s
  • 211
  • 3
  • 8
  • I did not, but I tried and still no luck. I edited the above problem with more info if needed, thanks. – Rob DePietro Nov 11 '20 at 14:11
  • So this is injected from some other js file ? – Akk3d1s Nov 12 '20 at 08:00
  • Yes, angular elements allows you to compile an angular app into a web component that then can be consumed by another application such as Angular or React and it interacts with the consuming application as a .js file and a html tag – Rob DePietro Nov 12 '20 at 13:13
0

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

0

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>
Cristian Sepulveda
  • 1,572
  • 1
  • 18
  • 25
-1

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

James
  • 2,516
  • 2
  • 19
  • 31
  • I've tried that as well previously. I believe it may have something to do with the elements-app not being part of the angular module since its an outside tag....not 100% sure though – Rob DePietro Nov 10 '20 at 17:07
  • Could you add any error messages you have? It would help a lot. Common issues are, as you mentioned. Not having the component included in a module. You also need `CommonModule` as an import in your app.module. – James Nov 11 '20 at 13:41
  • I am not getting any error messages. I have edited the problem with more information. Hopefully it makes sense, thanks. – Rob DePietro Nov 11 '20 at 14:11
  • I'd remove `CUSTOM_ELEMENTS_SCHEMA` as this tends to mask errors of the kind I think you're having. Also why are you injecting your `AppComponent` into your app module like that? If there is no specific reason, i'd remove it as it could be causing more issues. You also shouldn't need to add `AppComponent` as an entry component when you've done that. Just ensure it is in the `bootstrap` array and `declarations` array of your `AppModule`. – James Nov 11 '20 at 22:05