My mapping application broke with the upgrade to Google Maps JavaScript API v3.58 and above. I am trying to create a new google.maps.Polyline
using a custom class that extends the Polyline with a few new methods I use frequently.
The error in the console is as follows:
TypeError: Class constructors cannot be invoked without 'new'
at new CustomPolyline.Polyline (webpack-internal:///...tomPolygon.js:31:32)
I create instances of my custom class using
polylines.push(new CUST.CustomPolyline.Polyline(polygonType, this.mapInstance, polylineJSONObjects[i].coordinates, polylineJSONObjects[i].normalPolyAttributes, polylineJSONObjects[i].highlightPolyAttributes, polylineJSONObjects[i].normalPolyAttributes.mapLabelText));
The code executing is the constructor. I'm using a namespace called CUST and my extension is called CustomPolyline
'use strict';
(
function (window, CUST, google) {
if (typeof (CUST) === 'undefined') {
CUST = {};
}
CUST.CustomPolyline.Polyline = function(polyType, googleMap, dvgCoordinatesString,
normalPolyAttributes, highlightPolyAttributes,
labelText) {
// Constructor
if (this instanceof CustomPolyline.Polyline) {
try {
google.maps.Polyline.apply(this, arguments);
} catch (ex) {
// new Chrome update gave exception in 'apply' so used 'call'
google.maps.Polyline.call(this, arguments);
}
this.base = google.maps.Polyline.prototype;
<... constructor initialization code ...>
}
<... extension methods ...>
)(window, window.CUST, window.google);
If I switch to v3.57, this code works fine. I get the above error with any version newer than 3.57. I have reviewed all the release notes and see no indication of a breaking change in 3.58 that would cause this.
Could this be an ECMAScript version problem with the Google Maps API? If so, how can I fix it without rewriting my extension class completely (it's thousands of lines of code)?
Your code uses "function constructors" from the pre-ES6 world, and so did the Google Maps Javascript API until version 3.57. Search for
_.to=function(a){ro.call(this,a)};
in https://maps.googleapis.com/maps-api-v3/api/js/57/13/main.js, this is what eventually becomes google.maps.Polyline
.
But as of version 3.58 the Google Maps Javascript API uses ES6 classes, the code corresponding to google.maps.Polyline
in https://maps.googleapis.com/maps-api-v3/api/js/58/11a/main.js is
_.tq=class extends Ln{
See here for a comparison of the syntax. Importantly, ES6 constructors cannot be invoked without the new
keyword. Good question whether the switch to ES6 classes deserves to be called a breaking change and mentioned in the release notes.
You can change your code so that CUST.CustomPolyline.Polyline
is a subclass in the ES6 sense:
CUST.CustomPolyline.Polyline = class extends google.maps.Polyline {
constructor(polyType, googleMap, dvgCoordinatesString,
normalPolyAttributes, highlightPolyAttributes,
labelText) {
super(polyType, googleMap, dvgCoordinatesString,
normalPolyAttributes, highlightPolyAttributes,
labelText);
this.base = google.maps.Polyline.prototype;
<... constructor initialization code ...>
}
};
<... extension methods ...>
This assumes that you define your extension methods like
CUST.CustomPolyline.Polyline.prototype.method = function(...) {...}
But it would be more in line with the new ES6 class syntax to define them inside the class { ... }
.