mapsplugin / cordova-plugin-googlemaps

Google Maps plugin for Cordova
Apache License 2.0
1.66k stars 918 forks source link

Angular CDK Overlay not working when opened via marker click event #2827

Closed longinius closed 4 years ago

longinius commented 4 years ago

I'm submitting a ... (check one with "x")

OS: (check one with "x")

cordova information: (run $> cordova plugin list)

com.googlemaps.ios 3.9.0 "Google Maps SDK for iOS"
cordova-androidx-build 1.0.4 "cordova-androidx-build"
cordova-plugin-device 2.0.2 "Device"
cordova-plugin-googlemaps 2.8.0-20200709-2008 "cordova-plugin-googlemaps"
cordova-plugin-ionic-keyboard 2.2.0 "cordova-plugin-ionic-keyboard"
cordova-plugin-ionic-webview 4.2.1 "cordova-plugin-ionic-webview"
cordova-plugin-splashscreen 5.0.2 "Splashscreen"
cordova-plugin-statusbar 2.4.2 "StatusBar"
cordova-plugin-whitelist 1.3.3 "Whitelist"

If you use @ionic-native/google-maps, please tell the package.json (only @ionic-native/core and @ionic-native/google-maps are fine mostly)

@ionic-native/core : 5.27.0
@ionic-native/google-maps : 5.5.0

Current behavior: When the marker is clicked the overlay is displayed but not correctly positioned and missing text. The overlay is build with the Angular CDK using the overlay. It works fine, when using the button in the navigation bar. When opened from marker click event the position is not correct (only when not opened via button) and the text is missing. Sometimes after a delay it will position correctly and shows the text.

Since the problem only occurs when the overlay is opened via the marker click event, I guess it could be related to the plugin.

In the browser we have a special case, here the error occurs only if you test on smartphone size. In the normal window at full size the problem does not occur.

Expected behavior: The overlay should be correctly positioned and the text should be shown when opened via marker click event.

Screen capture or video record: Mobile Device: bug

Browser (Desktop and Mobile): bug2_720

Related code, data or error log (please format your code or data): Repository: https://github.com/longinius/ionic-native-maps-error

wf9a5m75 commented 4 years ago

Sorry. I have never used Angular CDK (what is that?). I have no idea.

faugusztin commented 4 years ago

The issue is not caused by the plugin nor Angular CDK, but by how Angular change detection (Zone.js) works. This is a common problem with code running outside the Angular change detection, most commonly present in Cordova plugin callbacks, as those run outside Angular Zones. The "delay" is then caused by change detection running on it's own few second late, picking up the changes from DOM tree and fixing it.

The overlay is opened using this code:

  public openOverlay() {
    this.attachOverlay('This text should be displayed');
  }

... later in same file ...

    const marker: Marker = await this.mapInstance.nativeMapObject.addMarker(markerOptions);
    marker.addEventListener(GoogleMapsEvent.MARKER_CLICK).pipe(
      untilDestroyed(this)
    ).subscribe({
      next: data => {
        console.log('marker', data);
        this.openOverlay();
      }
    });

The issue can be fixed using the NgZone.run method.

So in Tab1Page import NgZone :

import { Component, ComponentRef, ElementRef, NgZone, OnInit } from '@angular/core';

Add it to constructor for injection:

  constructor(
    private mapService: MapService,
    private platform: Platform,
    private overlay: Overlay,
    private overlayPositionBuilder: OverlayPositionBuilder,
    private elementRef: ElementRef,
    private ngZone: NgZone
  ) { }

And then use it:

  public openOverlay() {
    this.ngZone.run(()=> {
      this.attachOverlay('This text should be displayed');
    });
  }
wf9a5m75 commented 4 years ago

NgZone.run is common way, and it's not this plugin's problem.

Since the map is not a displayed in <body>, angular CA not know what happened.

That's why you need to use NgZone.run

longinius commented 4 years ago

Thank you for the information with NgZone. I had already thought about a problem with the change detection but was surprised about the different behaviour in the browser at lower screen resolutions.

The problem was on my side. Many thanks for the quick help.