googlemaps / js-markerclusterer

Create and manage clusters for large amounts of markers
https://googlemaps.github.io/js-markerclusterer/
Apache License 2.0
234 stars 87 forks source link

Angular usage & "allowSyntheticDefaultImports": true, #231

Closed VashJuan closed 2 years ago

VashJuan commented 2 years ago

Just a few tips for Angular users & a bug (I think).


Please be sure to include as much information as possible:

Environment details

Running on Win10 Pro insider, Chrome browser (latest), VSCode (insiders), all packages are evergreen

PS D:\Projects\RangerTrak\rangertrak> npm list rangertrak@0.11.38 D:\Projects\RangerTrak\rangertrak
├── @angular-devkit/build-angular@13.2.4 ├── @angular-material-components/color-picker@7.0.1
├── @angular-material-components/datetime-picker@7.0.1 ├── @angular/animations@13.2.3 ├── @angular/cdk@13.2.3 ├── @angular/cli@13.2.4 ├── @angular/common@13.2.3 ├── @angular/compiler-cli@13.2.3 ├── @angular/compiler@13.2.3 ├── @angular/core@13.2.3 ├── @angular/fire@7.2.1 ├── @angular/forms@13.2.3 ├── @angular/google-maps@13.2.3 ├── @angular/material@13.2.3 ├── @angular/platform-browser-dynamic@13.2.3 ├── @angular/platform-browser@13.2.3 ├── @angular/router@13.2.3 ├── @angular/service-worker@13.2.3 ├── @fortawesome/angular-fontawesome@0.10.1 ├── @fortawesome/fontawesome-svg-core@1.3.0 ├── @fortawesome/free-brands-svg-icons@6.0.0 ├── @fortawesome/free-regular-svg-icons@6.0.0 ├── @fortawesome/free-solid-svg-icons@6.0.0 ├── @googlemaps/markerclusterer@1.0.24 ├── @material/banner@13.0.0 ├── @material/slider@13.0.0 ├── @mdi/js@6.5.95 ├── @ngx-pwa/local-storage@13.0.2 ├── @popperjs/core@2.11.2 ├── @types/google-maps@3.2.3 ├── @types/google.maps@3.47.4 ├── @types/jasmine@3.10.3 ├── @types/leaflet.markercluster@1.4.6 ├── @types/leaflet@1.7.9 ├── @types/node@17.0.18 ├── @types/supercluster@5.0.3 extraneous ├── @what3words/api@4.0.4 ├── ag-grid-angular@27.0.0 ├── ag-grid-community@27.0.1 ├── dayjs@1.10.7 ├── firebase@9.6.7 ├── http-server@14.1.0 ├── jasmine-core@4.0.0 ├── jshint@2.13.4 ├── karma-chrome-launcher@3.1.0 ├── karma-coverage@2.2.0 ├── karma-jasmine-html-reporter@1.7.0 ├── karma-jasmine@4.0.1 ├── karma@6.3.16 ├── leaflet.markercluster@1.5.3 ├── leaflet@1.7.1 ├── rxfire@6.0.3 ├── rxjs@7.5.4 ├── tslib@2.3.1 ├── typescript@4.5.5 ├── xlsx-style@0.8.13 ├── xlsx@0.18.2 └── zone.js@0.11.4

Steps to reproduce

code is pretty much the same as listed in : https://github.com/googlemaps/js-markerclusterer (i.e., pretty simple) ng serve -o

Yields

`Warning: D:\Projects\RangerTrak\rangertrak\node_modules\@turf\clusters-dbscan\dist\es\index.js depends on 'density-clustering'. CommonJS or AMD dependencies can cause optimization bailouts. For more info see: https://angular.io/guide/build#configuring-commonjs-dependencies

Warning: D:\Projects\RangerTrak\rangertrak\node_modules\@turf\clusters-kmeans\dist\es\index.js depends on 'skmeans'. CommonJS or AMD dependencies can cause optimization bailouts. For more info see: https://angular.io/guide/build#configuring-commonjs-dependencies

Error: node_modules/@googlemaps/markerclusterer/dist/algorithms/supercluster.d.ts:18:8 - error TS1259: Module '"D:/Projects/RangerTrak/rangertrak/node_modules/@types/supercluster/index"' can only be default-imported using the 'allowSyntheticDefaultImports' flag

18 import SuperCluster, { ClusterFeature } from "supercluster";


  node_modules/@types/supercluster/index.d.ts:175:1
    175 export = Supercluster;
**This module is declared with using 'export =', and can only be used with a default import when using the 'allowSyntheticDefaultImports' flag.`**

To fix this, one needs to comprehend https://www.typescriptlang.org/tsconfig#allowSyntheticDefaultImports and then add the following line to your tsconfig.json file "compilerOptions": { "allowSyntheticDefaultImports": true,

Code example

So some tips for other Angular users: import { MarkerClusterer } from "@googlemaps/markerclusterer" fails, and I've had to go to: import * as GMC from "@googlemaps/markerclusterer"

then in the Component: gMap?: google.maps.Map markers: google.maps.Marker[] = [] markerCluster!: GMC.MarkerClusterer markerClustererImagePath = 'https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m'``

then in onMapInitialized(theGodGivenReferenceToTheActualGoogleMap: google.maps.Map) { this.map = theGodGivenReferenceToTheActualGoogleMap // Otherwise its near impossible for angular google map users to get the actual map reference & this is buried in git history, NOT well documented!

this.markerCluster = new GMC.MarkerClusterer({ map: this.map, markers: this.markers, // algorithm?: Algorithm, // renderer?: Renderer, // onClusterClick?: onClusterClickHandler, }) ... }

WARNING: do NOT use the Angular wrapper around google.maps.Marker & google.maps.MarkerMarkerClusterer!

github.com/angular/components/tree/master/src/google-maps/map-marker github.com/angular/components/tree/master/src/google-maps/map-marker-clusterer

For some reason these wrappers ONLY include lat/lng positions, and do not support Marker options: i.e. all your markers and clusters will look like identical clones and are pretty much mind-dead! (it is fine to use the rest of their wrappers, IF you are aware of the lightly documented onMapInitialized() event as shown above.)

Good luck & LOVE all the great work being done here!

jpoehnelt commented 2 years ago

As far as I can tell, there is nothing to do in this package to address this? Please reopen if there is.

VashJuan commented 2 years ago

Users of this package shouldn't be required to edit their tsconfig.json files and add "allowSyntheticDefaultImports": true, I do believe there is something the authors can do to help users avoid this. I don't know enough to suggest what that might be...

If nothing else the documentation should explain that this step is necessary.