-
Notifications
You must be signed in to change notification settings - Fork 90
jsvectormap does not work in Angular #75
Description
Loading jsvectormap in an Angular component does not work. The proper way to get a reference to the container element is to use the @ViewChild annotation and then load the map on ngAfterViewInit. Doing so causes a stack overflow (InternalError: too much recursion).
Steps to reproduce:
ng new
npm install jsvectormap
package.json
{
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"watch": "ng build --watch --configuration development",
"test": "ng test"
},
"private": true,
"dependencies": {
"@angular/animations": "~13.1.0",
"@angular/common": "~13.1.0",
"@angular/compiler": "~13.1.0",
"@angular/core": "~13.1.0",
"@angular/forms": "~13.1.0",
"@angular/platform-browser": "~13.1.0",
"@angular/platform-browser-dynamic": "~13.1.0",
"@angular/router": "~13.1.0",
"jsvectormap": "^1.4.5",
"rxjs": "~7.4.0",
"tslib": "^2.3.0",
"zone.js": "~0.11.4"
},
"devDependencies": {
"@angular-devkit/build-angular": "~13.1.2",
"@angular/cli": "~13.1.2",
"@angular/compiler-cli": "~13.1.0",
"@types/jasmine": "~3.10.0",
"@types/node": "^12.11.1",
"jasmine-core": "~3.10.0",
"karma": "~6.3.0",
"karma-chrome-launcher": "~3.1.0",
"karma-coverage": "~2.1.0",
"karma-jasmine": "~4.0.0",
"karma-jasmine-html-reporter": "~1.7.0",
"typescript": "~4.5.2"
}
}app.component.html
<div #map></div>app.component.ts
import {AfterViewInit, Component, ElementRef, ViewChild} from '@angular/core';
// @ts-ignore
import jsVectorMap from "jsvectormap";
import "jsvectormap/src/maps/world"
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent implements AfterViewInit {
@ViewChild('map')
private mapRef!: ElementRef<HTMLDivElement>;
ngAfterViewInit(): void {
new jsVectorMap({
selector: this.mapRef.nativeElement,
});
}
}Error in FireFox:
ERROR InternalError: too much recursion
toString zone.js:1571
t jsvectormap.min.js:1
t jsvectormap.min.js:1
r jsvectormap.min.js:1
o jsvectormap.min.js:1
i jsvectormap.min.js:1
s jsvectormap.min.js:1
s jsvectormap.min.js:1
o jsvectormap.min.js:1
i jsvectormap.min.js:1
r jsvectormap.min.js:1
r jsvectormap.min.js:1
o jsvectormap.min.js:1
i jsvectormap.min.js:1
s jsvectormap.min.js:1
s jsvectormap.min.js:1
o jsvectormap.min.js:1
i jsvectormap.min.js:1
r jsvectormap.min.js:1
...
Error in Chrome:
core.mjs:6461 ERROR RangeError: Maximum call stack size exceeded
at TView.Object.toString (polyfills.js:5945:42)
at vendor.js:938:1000
at Object.t [as isMergeableObject] (vendor.js:938:1096)
at i (vendor.js:938:1217)
at vendor.js:938:1343
at Array.map (<anonymous>)
at Object.s [as arrayMerge] (vendor.js:938:1319)
at o (vendor.js:938:2199)
at i (vendor.js:938:1238)
at vendor.js:938:1992
The error happens when merging the map's options. Specifically when iterating over the properties of the selector property which is, in this case, a HTMLDivElement. I suspect that the infinite recursion is due to the hierarchical nature of the DOM element (the DOM element holds a reference to it's parent and children which, in turn, hold a reference to their parent and children).
A solution would be to not merge the properties of DOM elements.