Skip to content
An Ember addon to allow lazy loading the ArcGIS API for JavaScript in Ember applications
JavaScript HTML CSS
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
addon removed deprecated `esriLoader.load()` in favor of `esriLoader.loadSc… Jul 25, 2019
app added esri-loader service Mar 12, 2017
config base upgrade Nov 13, 2018
tests fix template linting errors even though they're not the same ones I s… Jul 26, 2019
vendor added vendor shim for esri-loader Apr 8, 2017
.editorconfig Initial Commit from Ember CLI v2.11.1 Mar 10, 2017
.ember-cli Initial Commit from Ember CLI v2.11.1 Mar 10, 2017
.eslintignore base upgrade Nov 13, 2018
.eslintrc.js base upgrade Nov 13, 2018
.gitignore base upgrade Nov 13, 2018
.npmignore base upgrade Nov 13, 2018
.template-lintrc.js disable tmpl linting rules, get tests and dummy working Nov 14, 2018
.travis.yml literally no fucking idea Jul 26, 2019
.watchmanconfig Initial Commit from Ember CLI v2.11.1 Mar 10, 2017
CHANGELOG.md Released v3.0.0 Jul 26, 2019
CNAME added surge deploy and updated README Mar 13, 2017
CONTRIBUTING.md
LICENSE.md update to ember 2.18 Apr 24, 2018
README.md esri-loader is now a peer dependency and must be explicitly installed Jul 25, 2019
ember-cli-build.js remove bower and have dummy app get bootstrap from CDN Jul 25, 2019
index.js include config/environment in the fun Apr 18, 2019
license.txt add license comments and info in README for release Mar 27, 2017
package.json Released v3.0.0 Jul 26, 2019
preload-jsapi-in-ember.gif update repo url to esri org & add scene button to home page Mar 27, 2017
testem.js base upgrade Nov 13, 2018
yarn.lock tighten version range of ember-cli-surge hoping to fix ember-try errors Jul 26, 2019

README.md

ember-esri-loader

An Ember addon that wraps the esri-loader library to allow lazy loading and preloading the ArcGIS API for JavaScript in Ember applications.

An example of preloading the ArcGIS API

View it live.

See the esri-loader README for more information on why this is needed.

Installation

In your app's root folder run:

npm install esri-loader
ember install ember-esri-loader

Usage

Loading Modules from the ArcGIS API for JavaScript

Here's an example of how you could load and use the latest 4.x MapView and WebMap classes in a component to create a map:

// app/components/esri-map.js
export default Ember.Component.extend({
  layout,
  esriLoader: Ember.inject.service('esri-loader'),

  // once we have a DOM node to attach the map to...
  didInsertElement () {
    this._super(...arguments);
    // load the map modules
    this.get('esriLoader').loadModules(['esri/views/MapView', 'esri/WebMap']).then(modules => {
      if (this.get('isDestroyed') || this.get('isDestroying')) {
        return;
      }
      const [MapView, WebMap] = modules;
      // load the webmap from a portal item
      const webmap = new WebMap({
        portalItem: { // autocasts as new PortalItem()
          id: this.itemId
        }
      });
      // Set the WebMap instance to the map property in a MapView.
      this._view = new MapView({
        map: webmap,
        container: this.elementId
      });
    });
  },

  // destroy the map view before this component is removed from the DOM
  willDestroyElement () {
    if (this._view) {
      this._view.container = null;
      delete this._view;
    }
  }
});

See the esri-loader documentation on loading modules for more details.

Loading Styles

Before you can use the ArcGIS API in your app, you'll need to load the styles. See the esri-loader documentation on loading styles for more details.

Lazy Loading the ArcGIS API for JavaScript

The above code will lazy load the ArcGIS API for JavaScript the first time loadModules() is called. This means users of your application won't need to wait for the ArcGIS API to download until it is need.

Pre-loading the ArcGIS API for JavaScript

Alternatively, if you have good reason to believe that the user is going to transition to a map route, you may want to start pre-loading the ArcGIS API as soon as possible w/o blocking template rendering. You can add the following to the application route:

// app/routes/application.js
import Ember from 'ember';

export default Ember.Route.extend({
  esriLoader: Ember.inject.service('esri-loader'),

  renderTemplate: function () {
    // render the template as normal
    this._super(...arguments);
    // then preload the JSAPI
    // NOTE: to use the latest 4.x release don't pass any arguments to loadScript()
    this.get('esriLoader').loadScript()
    .catch(err => {
      // do something with the error
    });
  }
});

Now you can use loadModules() in components to create maps or 3D scenes. Also, if you need to, you can use isLoaded() anywhere in your application to find out whether or not the ArcGIS API has finished loading.

esri-module-cache mixin

This addon also includes a mixin that can be help mitigate one of the primary pain points of using esri-loader: accessing modules is always asynchronous. That's fine for modules like esri/map where you expect to be using them in an asynchronous operation (like creating a map). However, it can be cumbersome when you just need something like a new Graphic() to add to that map.

Services or components that implement the esri-module-cache mixin can load all the modules they may need up front during an async operation (such as creating a map), and then use the mixin's cacheModules() function to store references to any of those modules so they don't have to be loaded again. Later the getCachedModule() and newClassInstance() functions can be used to synchronously access and use the modules that have already been loaded. For example:

// map-service.js
import Service, { inject as service } from '@ember/service';
import EsriModuleCacheMixin from 'ember-esri-loader/mixins/esri-module-cache';

export default Service.extend(EsriModuleCacheMixin, {
  esriLoader: service('esri-loader'),
  loadMap (elemendId, options) {
    return thigs.get('esriLoader').loadModules([
      'esri/map',
      'esri/Graphic'
    ]).then(([Map, Graphic]) => {
      // cache graphic module later for synchronous use
      this.cacheModules({ Graphic });
      // create and return the map instance
      return new Map(elementId, options);
    });
  },
  // NOTE: this will throw an error if it is called before loadMap()
  newGraphic (...args) {
    return this.newClassInstance('Graphic', ...args);
  }
});
// my-map/component.js
export default Component.extend({
  layout,
  mapService: service(),

  // once we have a DOM node to attach the map to...
  didInsertElement () {
    this._super(...arguments);
    // load the map
    this.get('mapService').loadMap(this.elementId, { basemap: 'gray' })
    .then(map => {
      this.map = map;
    })
  },
  actions: {
    addGraphic (x, y) {
      if (!this.map) {
        // can't call newGraphic() unles map has loaded
        // also no point in creating a gaphic if there's no map to add it to
        return;
      }
      const graphicJson = {
        geometry: {
          x,
          y,
          spatialReference: {
            wkid: 4326
          }
        },
        symbol: {
          color: [255, 0, 0, 128],
          size: 12,
          angle: 0,
          xoffset: 0,
          yoffset: 0,
          type: 'esriSMS',
          style: 'esriSMSSquare',
          outline: {
            color: [0, 0, 0, 255],
            width: 1,
            type: 'esriSLS',
            style: 'esriSLSSolid'
          }
        }
      };
      const graphic =
      this.get('mapService').newGraphic(graphicJson);
      this.map.graphics.add(graphic);
    }
  }

How It Works

This addon is an implementation of the "Dedicated Loader Module" pattern for Ember. It is a mashup of the ideas from angular2-esri-loader and ember-cli-amd. Like angular2-esri-loader, it creates a service that exposes functions that wrap calls to the esri-loader library to load the ArcGIS API and it's modules in promises. However, in order to avoid global namespace collisions with loader.js's require() and define() this addon also has to steal borrow from ember-cli-amd the code that finds and replaces those terms with their pig-latin counterparts in the build output. However unlike ember-cli-amd, it does not inject the ArcGIS for JavaScript in the page, nor does it use the ArcGIS API's Dojo loader to load the entire app.

Limitations

You cannot use ES2015 module syntax for ArcGIS API modules (i.e. import Map from 'esri/map';) with this addon. If you do not feel that your application would benefit from lazy-loading the ArcGIS API, and you'd prefer the cleaner abstraction of being able to use import statements, you can use ember-cli-amd.

Using this addon to load ArcGIS API for JavaScript v4.x modules in tests run in PhantomJS may cause global errors. Those errors did not happen when running the same tests in Chrome or FireFox.

Also, this addon cannot be used in an Ember twiddle.

Examples

In addition to ArcGIS Online applications such as ArcGIS Hub, the following open source applications use this addon:

MyStreet - A municipality viewer that allows users to input an address and receive information based on that location uses this addon to lazy load v3.x of the ArcGIS API only when an app uses a map.

The dummy application for this addon demonstrates how to pre-load v4.x of the ArcGIS API.

Development Instructions

Fork, Clone, and Install

  • fork and clone the repository
  • cd ember-esri-loader
  • npm install

Linting

  • npm run lint:hbs
  • npm run lint:js
  • npm run lint:js -- --fix

Running Tests

  • ember test – Runs the test suite on the current Ember version
  • ember test --server – Runs the test suite in "watch mode"
  • ember try:each – Runs the test suite against multiple Ember versions

Building

For more information on using ember-cli, visit https://ember-cli.com/.

Issues

Find a bug or want to request a new feature? Please let us know by submitting an issue.

Contributing

Esri welcomes contributions from anyone and everyone. Please see our guidelines for contributing.

Licensing

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.

A copy of the license is available in the repository's license.txt file.

You can’t perform that action at this time.