/
esri-loader.js
89 lines (84 loc) · 3.52 KB
/
esri-loader.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
/*
Copyright 2017 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import Ember from 'ember';
export default Ember.Service.extend({
// emulate computed property isLoaded to indicate that the JSAPI been loaded
unknownProperty (key) {
if (key === 'isLoaded') {
return !!window.__dojoRequire;
}
},
// inject a script tag pointing to the JSAPI in the page
// and return a promise once it's loaded
load (options = {}) {
// if already loading or loaded, return the existing promise
if (this._loadPromise) {
return this._loadPromise;
}
// if loaded by other means (i.e. pre-existing script tag on the page)
if (this.get('isLoaded')) {
// TODO: check if same version of the JSAPI, then resolve like
// this._loadPromise = Ember.RSVP.resolve({ previouslyLoaded: true });
// return this._loadPromise;
// otherwise reject w/ error saying that a different version has been loaded
return Ember.RSVP.reject(new Error('The ArcGIS API for JavaScript is already loaded.'));
}
// otherwise create a promise that will resolve when the JSAPI is loaded
this._loadPromise = new Ember.RSVP.Promise((resolve, reject) => {
// create a script object whose source points to the API
const script = document.createElement('script');
script.type = 'text/javascript';
script.src = options.url || 'https://js.arcgis.com/4.3';
// once the script is loaded...
script.onload = () => {
// notify any watchers of isLoaded copmuted property
this.notifyPropertyChange('isLoaded');
// let the caller know that the API has been successfully loaded
// TODO: would there be something more useful to return here?
resolve({ success: true });
};
// reject on script error
script.onerror = () => {
reject(new Error(`Error while attempting to load ${script.src}`));
};
// load the script
document.body.appendChild(script);
});
return this._loadPromise;
},
// require the modules and return a pomise that reolves them as an array
loadModules (moduleNames) {
// TODO: validate that moduleNames is an array w/ at least one string?
// or just continue to let dojo throw "Cannot read property 'has' of undefined"?
if (this.get('isLoaded')) {
return this._loadModules(moduleNames);
} else {
if (this._loadPromise) {
// load modules once finished loadng the JSAPI
return this._loadPromise.then(Ember.run.bind(this, this._loadModules, moduleNames));
} else {
// not loaded or loading
return Ember.RSVP.reject(new Error('The ArcGIS API for JavaScript has not been loaded. You must first call esriLoader.load()'));
}
}
},
// require the modules and return a pomise that reolves them as an array
_loadModules (moduleNames) {
return new Ember.RSVP.Promise(resolve => {
// NOTE: this function name will be replaced at build time
window.__dojoRequire(moduleNames, (...modules) => {
resolve(modules);
});
});
}
});