Skip to content

Commit 55fd1b0

Browse files
tomwagneritsmichaeldiego
authored andcommitted
Google Map loader respecting the app language change (google-map-react#726)
1 parent 40fe3ea commit 55fd1b0

File tree

3 files changed

+68
-71
lines changed

3 files changed

+68
-71
lines changed

package.json

+1-2
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,7 @@
4848
},
4949
"dependencies": {
5050
"@mapbox/point-geometry": "^0.1.0",
51-
"eventemitter3": "^1.1.0",
52-
"scriptjs": "^2.5.7"
51+
"eventemitter3": "^1.1.0"
5352
},
5453
"devDependencies": {
5554
"autoprefixer": "^6.3.6",

src/loaders/google_map_loader.js

+67-65
Original file line numberDiff line numberDiff line change
@@ -1,87 +1,89 @@
11
const BASE_URL = 'https://maps';
22
const DEFAULT_URL = `${BASE_URL}.googleapis.com`;
3-
const API_PATH = '/maps/api/js?callback=_$_google_map_initialize_$_';
3+
const API_PATH = '/maps/api/js?callback=googleMapsAPILoadedPromise';
4+
const EVENT_GMAPS_LOADED = 'EVENT_GMAPS_LOADED';
45

5-
const getUrl = region => {
6+
const getBaseUrl = region => {
67
if (region && region.toLowerCase() === 'cn') {
78
return `${BASE_URL}.google.cn`;
89
}
910
return DEFAULT_URL;
1011
};
1112

12-
let $script_ = null;
13+
let currentResolver = null;
14+
let lastBaseUrl = '';
15+
let lastScriptUrl = '';
16+
let googleMapsPromise;
1317

14-
let loadPromise_;
15-
16-
let resolveCustomPromise_;
17-
18-
const _customPromise = new Promise(resolve => {
19-
resolveCustomPromise_ = resolve;
20-
});
21-
22-
// TODO add libraries language and other map options
23-
export default (bootstrapURLKeys, heatmapLibrary) => {
24-
if (!$script_) {
25-
$script_ = require('scriptjs'); // eslint-disable-line
26-
}
27-
28-
// call from outside google-map-react
29-
// will be as soon as loadPromise_ resolved
30-
if (!bootstrapURLKeys) {
31-
return _customPromise;
32-
}
18+
const destroyOldGoogleMapsInstance = url => {
19+
document
20+
.querySelectorAll(`script[src^='${url}']`)
21+
.forEach(script => script.remove());
22+
if (window.google) delete window.google.maps;
23+
};
3324

34-
if (loadPromise_) {
35-
return loadPromise_;
36-
}
25+
// Callback for the Google Maps API src
26+
window.googleMapsAPILoadedPromise = () =>
27+
window.dispatchEvent(new CustomEvent(EVENT_GMAPS_LOADED));
28+
29+
const getScriptUrl = bootstrapURLKeys => {
30+
const baseUrl = getBaseUrl(bootstrapURLKeys.region);
31+
const params = Object.keys(bootstrapURLKeys).reduce(
32+
(r, key) => `${r}&${key}=${bootstrapURLKeys[key]}`,
33+
''
34+
);
35+
return `${baseUrl}${API_PATH}${params}`;
36+
};
3737

38-
loadPromise_ = new Promise((resolve, reject) => {
39-
if (typeof window === 'undefined') {
40-
reject(new Error('google map cannot be loaded outside browser env'));
41-
return;
42-
}
38+
const loadScript = url => {
39+
const script = document.createElement('script');
4340

44-
if (window.google && window.google.maps) {
45-
resolve(window.google.maps);
46-
return;
47-
}
41+
script.type = 'text/javascript';
42+
script.async = true;
43+
script.src = url;
44+
document.querySelector('head').appendChild(script);
4845

49-
if (typeof window._$_google_map_initialize_$_ !== 'undefined') {
50-
reject(new Error('google map initialization error'));
46+
return new Promise(resolve => {
47+
if (currentResolver) {
48+
window.removeEventListener(EVENT_GMAPS_LOADED, currentResolver);
5149
}
52-
53-
window._$_google_map_initialize_$_ = () => {
54-
delete window._$_google_map_initialize_$_;
55-
resolve(window.google.maps);
50+
currentResolver = () => {
51+
resolve();
5652
};
53+
window.addEventListener(EVENT_GMAPS_LOADED, currentResolver);
54+
});
55+
};
5756

58-
if (process.env.NODE_ENV !== 'production') {
59-
if (Object.keys(bootstrapURLKeys).indexOf('callback') > -1) {
60-
const message = `"callback" key in bootstrapURLKeys is not allowed,
61-
use onGoogleApiLoaded property instead`;
62-
// eslint-disable-next-line no-console
63-
console.error(message);
64-
throw new Error(message);
65-
}
66-
}
67-
68-
const params = Object.keys(bootstrapURLKeys).reduce(
69-
(r, key) => `${r}&${key}=${bootstrapURLKeys[key]}`,
70-
''
71-
);
57+
const loadGoogleMaps = bootstrapURLKeys =>
58+
new Promise(async resolve => {
59+
lastScriptUrl = getScriptUrl(bootstrapURLKeys);
60+
await loadScript(lastScriptUrl);
61+
resolve(window.google.maps);
62+
});
7263

73-
const baseUrl = getUrl(bootstrapURLKeys.region);
74-
const libraries = heatmapLibrary ? '&libraries=visualization' : '';
64+
export default bootstrapURLKeys => {
65+
if (typeof window === 'undefined') {
66+
throw new Error('google map cannot be loaded outside browser env');
67+
}
7568

76-
$script_(
77-
`${baseUrl}${API_PATH}${params}${libraries}`,
78-
() =>
79-
typeof window.google === 'undefined' &&
80-
reject(new Error('google map initialization error (not loaded)'))
81-
);
82-
});
69+
if (process.env.NODE_ENV !== 'production') {
70+
if (Object.keys(bootstrapURLKeys).includes('callback')) {
71+
const message = `'callback' key in bootstrapURLKeys is not allowed, use onGoogleapiLoadedPromise property instead`;
72+
// eslint-disable-next-line no-console
73+
console.error(message);
74+
throw new Error(message);
75+
}
76+
}
77+
if (googleMapsPromise) {
78+
if (lastScriptUrl !== getScriptUrl(bootstrapURLKeys)) {
79+
destroyOldGoogleMapsInstance(lastBaseUrl);
80+
googleMapsPromise = loadGoogleMaps(bootstrapURLKeys);
81+
}
82+
return googleMapsPromise;
83+
}
8384

84-
resolveCustomPromise_(loadPromise_);
85+
googleMapsPromise = loadGoogleMaps(bootstrapURLKeys);
86+
lastBaseUrl = getBaseUrl(bootstrapURLKeys.region);
8587

86-
return loadPromise_;
88+
return googleMapsPromise;
8789
};

yarn.lock

-4
Original file line numberDiff line numberDiff line change
@@ -4989,10 +4989,6 @@ sax@^1.2.4, sax@~1.2.1:
49894989
version "1.2.4"
49904990
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
49914991

4992-
scriptjs@^2.5.7:
4993-
version "2.5.8"
4994-
resolved "https://registry.yarnpkg.com/scriptjs/-/scriptjs-2.5.8.tgz#d0c43955c2e6bad33b6e4edf7b53b8965aa7ca5f"
4995-
49964992
scss-tokenizer@^0.2.3:
49974993
version "0.2.3"
49984994
resolved "https://registry.yarnpkg.com/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz#8eb06db9a9723333824d3f5530641149847ce5d1"

0 commit comments

Comments
 (0)