Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to show dynamic content in @angular/google-maps infoWindow

Specifically, how do you show information related to the marker in the respective infoWindow?

By following the example on the repo here, the same information is opened for every marker. With the old angular google maps you could easily just insert the info window inside the marker with whatever data you wanted.

I saw a few examples of setting the content with {{ contentHere }} in the template, but that only allows for strings. I need to use all the angular template stuff like usual.

Let's say our template looks something like the repo example:

<google-map height="400px"
        width="750px"
        [center]="center"
        [zoom]="zoom">
  <map-marker #marker
          *ngFor="let place of places"
          [position]="{ lat: place.latitude, lng: place.longitude }"
          [options]="markerOptions"
          (mapClick)="openInfoWindow(marker)">

      <map-info-window>
        <-- this is what i'm concerned with -->
        {{ place.description }}
      </map-info-window>
  </map-marker>
</google-map>

And then we add viewchild like the repo example and open it in the same way:

@ViewChild(MapInfoWindow, {static: false}) infoWindow: MapInfoWindow;

openInfoWindow(marker: MapMarker) {
  this.infoWindow.open(marker);
}

Although this does open the correct marker and the marker will reflect dynamic info, this will show the same content / place.description for every info window, which isn't really surprising since a single ViewChild is being used. I've come up with all kinds of convoluted ways to do this and had a look through the source code but there doesn't seem to be an obvious and/or built in solution for displaying content in the window that is related to what is being used by the marker. It just seems weird to not have that as a basic example.

How would any of you go about doing this?

like image 910
Jason Simpson Avatar asked Jun 02 '20 00:06

Jason Simpson


2 Answers

Simplest way, hope it can help

TS

public openInfoWindow(marker: MapMarker, infoWindow: MapInfoWindow) {
    infoWindow.open(marker);
}

HTML

<google-map *ngIf="mapOptions.center" width="100%" height="100%" [options]="mapOptions">
    <ng-container *ngFor="let elem of elements">
        <map-marker #marker="mapMarker" [position]="elem.position" [options]="elem.markerOptions" (mapClick)="openInfoWindow(marker, infoWindow)"></map-marker>
        <map-info-window #infoWindow="mapInfoWindow"> Content of {{ elem.id }} ...</map-info-window>
    </ng-container>
</google-map>
like image 82
Fernando Cortese Avatar answered Oct 18 '22 21:10

Fernando Cortese


Use ViewChildren, use index in the for loop in the template, pass in the index when marker is clicked, loop through all ViewChildren using an index inside of a forEach (for loop with index will not open the window for some reason), then if the index of the loop matches the index passed in, open that window. It seems like there would be a better way than this but it's all I could come up with after trying many things:

In component:

@ViewChildren(MapInfoWindow) infoWindowsView: QueryList<MapInfoWindow>;

openInfoWindow(marker: MapMarker, windowIndex: number) {
  /// stores the current index in forEach
  let curIdx = 0;
  this.infoWindowsView.forEach((window: MapInfoWindow) => {
    if (windowIndex === curIdx) {
      window.open(marker);
      curIdx++;
    } else {
      curIdx++;
    }
  });
}

In template:

<google-map height="400px"
    width="750px"
    [center]="center"
    [zoom]="zoom">
  <map-marker #marker
      *ngFor="let place of places; let i = index" <-- added index -->
      [position]="{ lat: place.latitude, lng: place.longitude }"
      [options]="markerOptions"
      (mapClick)="openInfoWindow(marker, i)"> <-- pass in index -->

      <map-info-window>
        {{ place.description }}
      </map-info-window>
  </map-marker>
</google-map>

This will open the info window with its respective marker.

like image 6
Jason Simpson Avatar answered Oct 18 '22 22:10

Jason Simpson