Search code examples
angularmapquest

angular - reference html of another component from typescript


I am implementing mapQuest into my angular project. The map is working fine and also popups are showing however I have an issue with accessing another component HTML file. I managed to resolve it somewhat but I don't think it the right solution.

On the popup, I want to display another component where I have a table. I also need to provide input.

Example:

Parent html:

<div id="map" style="height: -webkit-fill-available; width: -webkit-fill-available;">       
     </div> 

   <app-basicInfo [input]="testInput"></app-basicInfo>  

This app-basicInfo should not be in HTML file. At the moment if I delete this then its the popup is not working.

Parent typescript - problem: here on bindPopup I want to show the child component.

   L.marker([35.7392, -104.9903], {
      icon: L.mapquest.icons.marker(),
      draggable: false
    }).bindPopup(this.child.getHtmlContent()).addTo(this.map); <-- here

My question in general would be how to achieve something like this:

bindPopup( "<app-basicInfo [input]="testInput"></app-basicInfo>" )

Child:

<app-table style="width: 100%;" [dataSource]="dataSource" [displayedColumns]="displayedColumns">
<ng-content></ng-content>
</app-table>

Child TS:

  constructor(elRef: ElementRef) {
    this.elRef = elRef;
   }
  getHtmlContent() {
    return this.elRef.nativeElement.innerHTML;
  }

I cannot find an answer and I have read a lot of documentation. I would appreciate even some reference to some file where something like this is resolved.


Solution

  • Based on https://github.com/Asymmetrik/ngx-leaflet/issues/178 I managed to resolve it.

    First I installed angular/elements.

    Added this to my sharedModule:

    export class SharedModuleModule {
      constructor(private injector: Injector) {
        const PopupElement = createCustomElement(BasicInfoComponent, {injector});
        // Register the custom element with the browser.
        customElements.define('popup-element', PopupElement);
      }
     }
    

    And implemented the marked calling my basic info component:

    L.marker([35.7392, -104.9903], {
          icon: L.mapquest.icons.marker(),
          draggable: false
        }).addTo(this.map).bindPopup(fl => {
          const popupEl: NgElement & WithProperties<BasicInfoComponent> = document.createElement('popup-element') as any;
          popupEl.message="test";
          popupEl.addEventListener('closed', () => document.body.removeChild(popupEl));
          document.body.appendChild(popupEl);
          return popupEl;
        })