Diesel
Diesel

Reputation: 5355

Ionic 4 / Angular 7 button working in Google Maps Marker InfoWindow

Update: The element on the button in a Google Maps InfoWindow under an element inspector looks like:

<ion-button href="/tabs/(map:place/135)" routerdirection="forward" ion-activatable="" class="button button-solid hydrated">Details</ion-button>

But a button on a normal page looks like (it has more things in it):

<ion-button _ngcontent-c1="" href="/tabs/(home:place/135)" routerdirection="forward" ng-reflect-router-direction="forward" ng-reflect-href="/tabs/(home:place/135)" ion-activatable="" class="button button-solid hydrated">Details</ion-button>

Why?

I put a break in @ionic/angular/dist/directives/navigation/href-delegate.js on line 34 (HrefDelegate.prototype.onClick) and it breaks if I use a button on a normal page (exactly the same text), but not if I click my button in the google maps InfoWindow.


I’m attempting to pass a routerDirection (ionic) from a google maps marker. The more general issue is I'm trying to do angular things in an infoWindow. The user clicks the marker, it shows a box which contains a button which has a routerDirection. routerDirection from a normal button works for me, but not from the infoWindow.

When using the marker content for a transition forward, I get no back button on the next page. I don’t have a defaultHref on the ion back button on the next page, and if I did it would show a back button, but always use the defaultHref which isn’t the intent. I want it to navigate back to my map tab, but it doesn’t seem to know where I navigated forward from.

I have a map component page and a google-map component which does most of the work. When I create a marker, I pass it content to display (there are two buttons for testing):

      const content = `
      <h5>${place.name}</h5>
      <p>${place.description}</p>
      <ion-button href="/tabs/(map:place/135)" routerDirection="forward">Details</ion-button>
      <ion-button routerDirection='forward' href='/tabs/(map:place/${place.id})'>Details</ion-button>
      `;
      markers.push({ lat: place.lat, lng: place.lon, title: place.name, content: content });
    }
    if (typeof this.map !== 'undefined') {
      this.map.addMarkers(markers);
    }

this.map refers to the google map component I mentioned earlier.

@ViewChild(GoogleMapComponent) map?: GoogleMapComponent;

And in my addMarkers method in the google-map component it adds the content as follows:

const marker = new google.maps.Marker(options);

if (typeof location.content !== 'undefined') {
const infoWindow = new google.maps.InfoWindow({
  content: location.content
});
marker.addListener('click', () => {
  if (typeof this.infoWindow !== 'undefined') {
    this.infoWindow.close();
  }
  infoWindow.open(this.map, marker);
  this.infoWindow = infoWindow;
});

So, when I click on the button in the marker content (after clicking on the marker), I navigate but get no back button. Any ideas? Thank you for any help.

Upvotes: 1

Views: 1929

Answers (1)

Diesel
Diesel

Reputation: 5355

There is no $compile in Angular 2+. So instead of using navigateFoward which I think isn't being properly compiled I used the .navigateForward method and link to that via html that contains an element ID. And I use that element ID to pass a function.

I have a custom type for my markers to pass to my function which is:

locations: {
lat: number, lng: number,
content?: { title: string, html: string,
  click?: {clickElementId: string, clickFunction: () => void }}}[]

So I must pass a lat/lng, and I can provide additional content that includes a title and some html for an infoWindow, and if I want to further customize it I can include an element that is clicked on and a function to go with it.

Now below is the function that accepts that type and works the markers inside a loop:

for (const location of locations) {
const latLng = new google.maps.LatLng(location.lat, location.lng);

  const options: google.maps.MarkerOptions = {
    map: this.map,
    animation: google.maps.Animation.DROP,
    position: latLng
  };

  const marker = new google.maps.Marker(options);

  if (typeof location.content !== 'undefined') {
    marker.setTitle(location.content.title);
    const infoWindow = new google.maps.InfoWindow({
      content: location.content.html
    });
    marker.addListener('click', () => {
      infoWindow.open(this.map, marker);
      this.infoWindow = infoWindow;
    });

    infoWindow.addListener('domready', () => {
      if (typeof location.content !== 'undefined' && typeof location.content.click !== 'undefined') {
        const element = document.getElementById(location.content.click.clickElementId);
        if (element) {
          element.addEventListener('click', location.content.click.clickFunction);
        }
      }
    });
  }
markers.push(marker);
}

Now I can call this function after setting up my makers to properly navigate forward as such:

        const content = (`
          <h5>${place.name}</h5>
          <p>${place.description}</p>
          <ion-button id='infoWindowButton'>Details</ion-button>
          `);
        markers.push({
            lat: place.lat, lng: place.lon, content: {
              title: place.name, html: content,
              click: {
                clickElementId: 'infoWindowButton', clickFunction: () => {
                  this.navCtrl.navigateForward(`/tabs/(map:place/${place.id}`);
                }
              }
            }
          });

Upvotes: 1

Related Questions