Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save tomwayson/e6260adfd56c2529313936528b8adacd to your computer and use it in GitHub Desktop.
Save tomwayson/e6260adfd56c2529313936528b8adacd to your computer and use it in GitHub Desktop.
How to use angular2-esri-loader in an angular-cli application

Adding angular2-esri-loader to the app and creating a map

NOTE: These instructions apply to trying to use the ArcGIS API for JavaScript in an Angular 2 application created w/ angular-cli. If you're working with more recent versions of Angular, you should use https://github.com/Esri/esri-loader instead.

  1. Create a new Angular app by using angular-cli to generate a new project

  2. Install angular2-esri-loader

npm install angular2-esri-loader esri-loader --save
  1. Generate a new component with ng g component esri-map and use EsriLoaderService to show a map
  1. Add the following to the bottom of the import statements in your application's module:
import { EsriLoaderService } from 'angular2-esri-loader';
import { EsriMapComponent } from './esri-map/esri-map.component';
  1. Add the following to your application's declarations:
EsriMapComponent
  1. Add the following to your application's providers to register angular2-esri-loader's EsriLoaderService:
EsriLoaderService
  1. Add the following to the end of your application component's template:
<app-esri-map></app-esri-map>

That's it, run the app with ng serve

Adding the ArcGIS API for JavaScript types

  1. Install the types
npm install @types/arcgis-js-api --save-dev
  1. Add "arcgis-js-api" to compilerOptions.types in src/tsconfig.app.json and src/tsconfig.spec.json
  2. Replace the contents of esri-map.component.ts with the contents of esri-map-with-types.component.ts

Re-run the app with ng serve

import { Component, OnInit, ViewChild, ElementRef } from '@angular/core';
// also import the "angular2-esri-loader" to be able to load JSAPI modules
import { EsriLoaderService } from 'angular2-esri-loader';
@Component({
selector: 'app-esri-map',
templateUrl: './esri-map.component.html',
styleUrls: ['./esri-map.component.css']
})
export class EsriMapComponent implements OnInit {
// for JSAPI 4.x you can use the "any for TS types
public mapView: __esri.MapView;
// this is needed to be able to create the MapView at the DOM element in this component
@ViewChild('mapViewNode') private mapViewEl: ElementRef;
constructor(
private esriLoader: EsriLoaderService
) { }
public ngOnInit() {
// only load the ArcGIS API for JavaScript when this component is loaded
return this.esriLoader.load({
// use a specific version of the JSAPI
url: 'https://js.arcgis.com/4.3/'
}).then(() => {
// load the needed Map and MapView modules from the JSAPI
this.esriLoader.loadModules([
'esri/Map',
'esri/views/MapView'
]).then(([
Map,
MapView
]: [ __esri.MapConstructor, __esri.MapViewConstructor]) => {
const mapProperties: __esri.MapProperties = {
basemap: 'hybrid'
};
const map = new Map(mapProperties);
const mapViewProperties: __esri.MapViewProperties = {
// create the map view at the DOM element in this component
container: this.mapViewEl.nativeElement,
// supply additional options
center: [-12.287, -37.114],
zoom: 12,
map // property shorthand for object literal
};
this.mapView = new MapView(mapViewProperties);
});
});
}
}
/* import the required JSAPI css */
@import 'https://js.arcgis.com/4.3/esri/css/main.css';
.esri-view {
height: 500px;
}
<h1>
Esri JSAPI with
<a href="https://github.com/tomwayson/angular2-esri-loader" target="_blank">
<code>angular2-esri-loader</code>
</a>
</h1>
<div #mapViewNode></div>
import { Component, OnInit, ViewChild, ElementRef } from '@angular/core';
// also import the "angular2-esri-loader" to be able to load JSAPI modules
import { EsriLoaderService } from 'angular2-esri-loader';
@Component({
selector: 'app-esri-map',
templateUrl: './esri-map.component.html',
styleUrls: ['./esri-map.component.css']
})
export class EsriMapComponent implements OnInit {
// for JSAPI 4.x you can use the "any for TS types
public mapView: any;
// this is needed to be able to create the MapView at the DOM element in this component
@ViewChild('mapViewNode') private mapViewEl: ElementRef;
constructor(
private esriLoader: EsriLoaderService
) { }
public ngOnInit() {
// only load the ArcGIS API for JavaScript when this component is loaded
return this.esriLoader.load({
// use a specific version of the JSAPI
url: 'https://js.arcgis.com/4.3/'
}).then(() => {
// load the needed Map and MapView modules from the JSAPI
this.esriLoader.loadModules([
'esri/Map',
'esri/views/MapView'
]).then(([
Map,
MapView
]) => {
const mapProperties: any = {
basemap: 'hybrid'
};
const map: any = new Map(mapProperties);
const mapViewProperties: any = {
// create the map view at the DOM element in this component
container: this.mapViewEl.nativeElement,
// supply additional options
center: [-12.287, -37.114],
zoom: 12,
map // property shorthand for object literal
};
this.mapView = new MapView(mapViewProperties);
});
});
}
}
@jrvaliente
Copy link

jrvaliente commented Aug 1, 2017

Hi, I have a problem with this. I followed the steps indicated but when I start the page I get the following error:

Uncaught Error: Can't resolve all parameters for EsriMapComponent: (?). ------------------------------------------------compiler.es5.js:16000
at syntaxError (http://localhost:4200/vendor.bundle.js:49418:34)
at CompileMetadataResolver.webpackJsonp.../../../compiler/@angular/compiler.es5.js.CompileMetadataResolver._getDependenciesMetadata (http://localhost:4200/vendor.bundle.js:63497:35)
at CompileMetadataResolver.webpackJsonp.../../../compiler/@angular/compiler.es5.js.CompileMetadataResolver._getTypeMetadata (http://localhost:4200/vendor.bundle.js:63365:26)
at CompileMetadataResolver.webpackJsonp.../../../compiler/@angular/compiler.es5.js.CompileMetadataResolver.getNonNormalizedDirectiveMetadata (http://localhost:4200/vendor.bundle.js:62960:24)
at CompileMetadataResolver.webpackJsonp.../../../compiler/@angular/compiler.es5.js.CompileMetadataResolver.loadDirectiveMetadata (http://localhost:4200/vendor.bundle.js:62824:25)
at http://localhost:4200/vendor.bundle.js:74534:72
at Array.forEach (native)
at http://localhost:4200/vendor.bundle.js:74533:72
at Array.forEach (native)
at JitCompiler.webpackJsonp.../../../compiler/@angular/compiler.es5.js.JitCompiler._loadModules (http://localhost:4200/vendor.bundle.js:74530:75)

Any idea why this is happening ???

Thank you

@jhonemillan
Copy link

jhonemillan commented Sep 3, 2017

Hi, i have a problem trying to use other modules that not belogs to Map, and MapView. for example SimpleMakerSymbol.
i can load the modules in this.esriLoader.loadModules method? right now, i get error cannot find name

public ngOnInit() {
// only load the ArcGIS API for JavaScript when this component is loaded
return this.esriLoader.load({
// use a specific version of the JSAPI
url: 'https://js.arcgis.com/4.4/'
}).then(() => {
// load the needed Map and MapView modules from the JSAPI
this.esriLoader.loadModules([
'esri/Map',
'esri/views/MapView',
'esri/geometry/Polyline',
'esri/symbols/SimpleMarkerSymbol',
'esri/Graphic'
]).then(([
Map,
MapView
]) => {
const mapProperties: any = {
basemap: 'topo',

    };

    const map: any = new Map(mapProperties);

    const mapViewProperties: any = {
      // create the map view at the DOM element in this component
      container: this.mapViewEl.nativeElement,
      // supply additional options
      center: [ -76.519722, 3.44],
      zoom: 12,
      
      map // property shorthand for object literal,

    };

    this.mapView = new MapView(mapViewProperties);
    var symbol = new SimpleMarkerSymbol({
      style: "square",
      color: "blue",
      size: "8px",  // pixels
      outline: {  // autocasts as esri/symbols/SimpleLineSymbol
        color: [ 255, 255, 0 ],
        width: 3  // points
      }
    });

@tyler-austin
Copy link

Thanks Tom, great work, I got it up and running! I got a question that I am hoping you have an answer for.

In angular-esri-map, in order for another component to get reference to the map object you guided us to use a registry pattern:

        esriRegistry.get('MainMapDirective').then(function (esriApp) {
            map = esriApp.map;
        });

Do you have any advice as to how to pass reference of the map object using angular2-esri-loader?

Thanks again!

@tomwayson
Copy link
Author

@jrvaliente @jhonemillan @tyler-austin

I apologize. I have not been getting any notifications about comments on this gist.

@jhonemillan

You need to include the other classes in the destructured array that gets passed to .then()

this.esriLoader.loadModules([
'esri/Map',
'esri/views/MapView',
'esri/geometry/Polyline',
'esri/symbols/SimpleMarkerSymbol',
'esri/Graphic'
]).then(([
Map,
MapView,
Polyline,
SimpleMarkerSymbol,
Graphic
]) => {

@tyler-austin

I'm not doing any work in Angular, so I can't really advise on best practices for inter-component communication. In the Ember apps I work on, we isolate all mapping code in services and components share access to the map through the service.

@tomwayson
Copy link
Author

Please don't leave any further comments here, I won't be notified and the gist is outdated. See https://github.com/Esri/esri-loader for the most up to date information on how to use the ArcGIS API for JavaScript in Angular applications.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment