tomwayson / angular-esri-loader Goto Github PK
View Code? Open in Web Editor NEWDEPRECATED: An Angular service to help you load ArcGIS API for JavaScript Modules
License: Apache License 2.0
DEPRECATED: An Angular service to help you load ArcGIS API for JavaScript Modules
License: Apache License 2.0
I created a cli Angular4 app, i followed the 'How to use angular2-esri-loader in an angular-cli application' instructions. It works fine when i run it with esri 4.x version but when i try to switch to 3.x i get a 404 Not Found error when retrieving 'http://js.arcgis.com/3.20/esri/views/MapView.js.' I can tell that the file doesn't exist, my question is do i need to make additional changes to get the esri loader to work with the esri 3.x version?
Hi Tom,
I successfully used angular-esri.loader, and I try to add single point to my map loading 'esri/geometry/Point', 'esri/SpatialReference', 'esri/symbols/SimpleMarkerSymbol' and 'esri/graphic' , but I don't understand how to add a point to a map.
Following my esri-map.component.ts ngOnInit():
return this.esriLoader.load({
url: '//js.arcgis.com/3.21/'
}).then(() => {
this.esriLoader.loadModules(['esri/map', 'esri/geometry/Point', 'esri/SpatialReference', 'esri/symbols/SimpleMarkerSymbol', 'esri/graphic']).then(([Map, Point, SpatialReference, SimpleMarkerSymbol, Graphic]) => {
this.map = new Map(this.mapEl.nativeElement, {
center: [11, 45],
zoom: 5,
basemap: 'gray',
showAttribution: false,
logo: false
});
var point = new Point(11, 45);
var simpleMarkerSymbol = new SimpleMarkerSymbol();
var graphic = new Graphic(point, simpleMarkerSymbol);
this.map.graphics.add(graphic);
});
});
The error is on "this.map.graphics.add(graphic);"
Following the error:
Uncaught (in promise): TypeError: Cannot read property 'add' of undefined
TypeError: Cannot read property 'add' of undefined
Can you help me please?
Sorry but I didn't find any example of "adding point to map" using esriLoader.
Tnx
Is there any way to unload the loaded JS objects?
I'm using arcgis JS api 3.x and 4.x together in my project due to some features haven't ported to 4.x yet.
When I load the 4.x after the 3.x it throws error. So how should I handle this?
I'm using angularjs 5.
I read that the dojo AMD loader has undef method, can I call this method?:
http://dojotoolkit.org/reference-guide/1.10/loader/amd.html#loader-amd
Thanks to "it's just Angular" we should rename to angular-esri-loader.
I'm thinking of releasing the changes in #12 as angular-esri-loader v1.0.0 and that will be what is officially compatible w/ angular v4.0+
We'll leave the existing published release of [email protected] out there as a library that is compatible angular v2.
As far as this repo goes, beyond changing the name in all the places, the only thing I can think that should be done is to rename the existing v1.0.0 tag to something like "angular2-esri-loader-v.1.0.0" or something. Then we can use the v1.0.0 tag to point to angular-esri-loader's v1.0.0.
Is that too confusing?
Another option is that we can pull a google on people and just start angular-esri-loader at v4.0.0?
Thoughts? Feelings?
I've seen some examples about implementing clustering via esri-system-js or https://github.com/nickcam/FlareClusterLayer. Are there any suggestions as to the best approach to get a clustering layer working with angular-esri-loader?
Hello,
I followed the angular CLI gist, all is working great, and I'm currently trying to trigger click events on a GraphicsLayer that I added to the map.
There is no way to trigger this event, and I can't figure out why.
The code I put in the esri-map.component.ts :
...
public ngOnInit() {
...
const mapProperties: __esri.MapProperties = {
basemap: 'streets'
};
const map = new Map(mapProperties);
const mapViewProperties: __esri.MapViewProperties = {
// create the map view at the DOM element in this component
container: this.mapViewEl.nativeElement,
center: [165.69, -21.20],
zoom: 7,
map
};
this.mapView = new MapView(mapViewProperties);
var points = [
{x: 166.454, y:-22.306},
{x: 166.442, y:-22.291},
{x: 166.457, y:-22.29},
{x: 166.4356, y:-22.3026}
];
var layer = new GraphicsLayer();
points.forEach(point => {
let g = new Graphic({
geometry: new Point({
x: point.x,
y: point.y
}),
attributes: {
index: 0
},
symbol: new PictureMarkerSymbol({
url: 'http://www.myiconfinder.com/uploads/iconsets/256-256-a5485b563efc4511e0cd8bd04ad0fe9e.png',
width: 20,
height: 20,
yoffset: 10
})
});
layer.add(g);
});
layer.on('click', function(){
console.log("click");
});
map.layers.add(layer);
});
});
}
}
And i got this error :
Failed to compile.
C:/dev/workspace/poc-sig/src/app/esri-map/esri-map.component.ts (105,23): Argument of type '"click"' is not assignable to parameter of type '"layerview-destroy"'.
I don't understand what is wrong, this is a working example of a similar action in JavaScript (log is ok in console) : http://jsfiddle.net/uphyh41h/
Thank you,
Ludovic
Hi
After recommendation from this post Esri/esri-loader#29 I'm trying to change logic, based angular-esri-loader solution
But I can't understood why problem appear like this
I'm trying multiple times from different solutions but I can't to do it work.
Information update only. The current version number is taking many folks by surprise.
Items of note:
Angular breaking changes of note:
When I want to use Observable.fromEvent(this.mapView,"click") method,
there are errors printed in browser console:
core.es5.js:1084 ERROR Error: Uncaught (in promise): TypeError: Invalid event target
TypeError: Invalid event target
at Function.webpackJsonp.1152.FromEventObservable.setupSubscription (FromEventObservable.js:113)
at FromEventObservable.webpackJsonp.1152.FromEventObservable._subscribe (FromEventObservable.js:135)
at FromEventObservable.Observable._trySubscribe (Observable.js:57)
at FromEventObservable.Observable.subscribe (Observable.js:45)
at esri.component.ts:135
How can I make it work? thanks
It would be really nice to be able to use the latest and greatest of this without having to upgrade our whole app to Angular 4. Since this only requires NgModule
and Injectable
from @angular/core
it should be as simple as making the version something like "angular/core": ^2.0.0 || ^4.0.0
in package.json
@noahmulfinger or @araedavis you should be able to take care of this.
Now that esri-loader exposes a promise-based API is this library still needed?
The problem is I'm so far out of the Angular game that I'm no longer qualified to even answer that question much less do anything about it. Whereas I can say w/ certainty that ember-esri-loader is definitely needed to get esri-loader in Ember.js apps.
Never mind trying keep this library up to date w/ all the churn in Angular, it hasn't even been updated for recent esri-loader releases. So it will still default to JSAPI 4.3, which is two minor versions behind the latest JSAPI.
Does anyone know of some special sauce that this library adds to make esri-loader easier to use in an Angular app? The NgModule? Is that needed?
If not, what I'd like to see is a couple of the projects that use this library (https://www.npmjs.com/package/angular-esri-components and/or developers.arcgis.com?) try to use the latest esri-loader directly instead. Hopefully we should be able to distill a pattern (npm i esri-loader
, a sample service or component snippet, etc), that is simple enough to document it in the README of this library, and then we can deprecate it. There might be a couple of issues around types since I haven't yet configured package.json w/ "types" (nor "module" etc), and generally don't know how a TS lib should be publishing them, but I'm willing to make changes in esri-loader needed to accommodate it's direct use in Angular apps.
On the other hand, if this library is still needed, then I'll need someone else to take ownership of it. If that someone is from Esri, then they should start a PR to make the changes needed to transfer to the Esri org (I can help w/ that).
I haven't looked into this yet. Got the following warning message when running npm install angular-esri-loader
on a fresh directory:
[email protected] /<my_application_path/
├─┬ [email protected]
│ └── [email protected]
└── UNMET PEER DEPENDENCY [email protected]
npm WARN [email protected] requires a peer of rxjs@^5.3.0 but none was installed.
@tomwayson after a bit of experimentation I figured out how to properly use the Typescript definitions for the JS API and I think we should document it here for users.
For JS API 3.x
npm install @types/arcgis-js-api
(for Typescript 2.0) or install with typings for Typescript 1.x.__esri
namespace like __esri.Map
.For JS API 4.x
src/@types
.__esri
namespace like __esri.Map
.The updated EsriMapComponent
looks like this:
import { Component, OnInit, ViewChild, ElementRef } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
@Component({
selector: 'app-esri-map',
templateUrl: './esri-map.component.html',
styleUrls: ['./esri-map.component.css']
})
export class EsriMapComponent implements OnInit {
@ViewChild('map') mapEl: ElementRef;
map: __esri.Map; // VS Code (and others) will now autocomplete on `this.map` like a boss.
constructor(private route: ActivatedRoute) {}
ngOnInit() {
if (this.map) {
// map is already initialized
return;
}
// get the required esri classes from the route
const esriModules = this.route.snapshot.data['esriModules'];
this._createMap(esriModules);
}
// create a map at the root dom node of this component
_createMap([Map]) {
this.map = new Map(this.mapEl.nativeElement, {
center: [-118, 34.5],
zoom: 8,
basemap: 'dark-gray'
});
}
}
In package.json, the main
entry is set to index.ts
. This causes an error when I am importing, as the export
syntax is not recognized.
Suggested Fix: Removing the main
entry will set the default entry point back to index.js
. This fixes my error, and esri-angular-cli-example still worked correctly in a local run when I included this change.
I will go ahead and make a PR for this, unless there is some specific reason index.ts needs to be the main entry point. (As a curious side note, I could only see this error when I loaded the package from npm install. When I loaded it locally through npm link, this error did not occur.)
cc @patrickarlt This branch has the error for reference.
Hi, I'm looking for an advice for my current issue. In my former app, I was overriding some esri classes and used them with my own namespace 'application/XXX'.
For example:
define(["dojo/_base/declare", "esri/dijit/editing/Delete", "application/Add"], function(declare, Delete, Add){
return declare(Delete, {
constructor: function (args) {
this.inherited(arguments);
args = args || {};
this._add = new Add({
featureLayer: args.featureLayer,
addedGraphics: args.deletedGraphics,
undoManager: args.undoManager
});
},
...
});
});
Do you have any tips, how to override ESRI JS API classes in similarly way, but using Angular EsriLoader? Is it necessary, to make my own API build or something like that?
Thank you
Hi Tom, Great work, thank you!
I'm planing on using your angular2 esri loader in my angular2, GIS focused application, where the map (and many features of the esri API) will be used on every page.
If I load a module, for Example the FeatureLayer js in one component, will a second component request the FeatureLayer.js a second time, or are files loaded only once?
Thanks a lot, Kevin
The section I just added to the esri-angular-cli-example probably belongs in this repo's README and then that repo can link back here.
Ditto for @jwasilgeo's gist for angular2-webpack-starter.
I'm picturing new subsections under Usage for each.
Maybe this is a note to self more than anything else, but current release process is:
git add .
git commit
npm run build
cd dist
npm publish
cd ..
git tag <version>
git push origin master --tags
Would be good to automate that. Also, the current scripts are out of date and do not reflect that process.
When angular-esri-loader
is included in a project and bundled (like with webpack) it is including its own copies of some code from @angular
as evidenced by this screencap of source-map-explorer
:
I think the accepted pattern is to specify the Angular dependencies in BOTH peerDependencies
and devDependencies
like now ngx-datatable
does it https://github.com/swimlane/ngx-datatable/blob/master/package.json#L66-L137. This should tell NPM that angular-esri-loader
needs a peerDependency
of @angular/core
when being installed as a dependency as opposed to installing a specific version.
@noahmulfinger or @araedavis you should be able to take care of this.
How I can use this example https://github.com/tomwayson/angular-esri-loader for multiple modules
For example I already have one module map
import { Component, OnInit, ViewChild, ElementRef } from "angular/core";
import { EsriLoaderService } from "angular-esri-loader";
@Component({
selector: "app-esri-map",
templateUrl: "./esri-map.component.html",
styleUrls: ["./esri-map.component.css"]
})
export class EsriMapComponent implements OnInit {
@ViewChild("map") mapEl: ElementRef;
map: any;
constructor(private esriLoader: EsriLoaderService) { }
ngOnInit() {
// only load the ArcGIS API for JavaScript when this component is loaded
return this.esriLoader.load({
// use a specific version of the API instead of the latest
url: "//js.arcgis.com/3.18/"
}).then(() => {
// load the map class needed to create a new map
this.esriLoader.loadModules(["esri/map"]).then(([Map]) => {
// create the map at the DOM element in this component
this.map = new Map(this.mapEl.nativeElement, {
center: [-118, 34.5],
zoom: 8,
basemap: "dark-gray"
});
});
});
}
}
Now I want add new component for example search
How I should use it ?
import { Component, OnInit, ViewChild, ElementRef } from "@angular/core";
import { EsriLoaderService } from "angular-esri-loader";
@Component({
selector: "app-esri-search",
templateUrl: "./esri-search.component.html",
styleUrls: ["./esri-search.component.css"]
})
export class EsriSearchComponent implements OnInit {
@ViewChild("mapSearch") mapElSearch: ElementRef;
map: any;
constructor(private esriLoader: EsriLoaderService) { }
ngOnInit() {
// only load the ArcGIS API for JavaScript when this component is loaded
return this.esriLoader.load({
// use a specific version of the API instead of the latest
url: "//js.arcgis.com/3.18/"
}).then(() => {
// load the map class needed to create a new map
this.esriLoader.loadModules([''esri/dijit/Search'']).then(([Search]) => {
// create the map at the DOM element in this component
var search = new Search({
map: this.map //Reference to the map.
}, this.mapElSearch.nativeElement);
console.log("search.startup");
search.startup();
});
});
}
}
**If I use as you see above I will have script error multiple arcgis library loaded, it loaded multiple times **
Hello,
I'm using your package with cordova. In web browser it works properly but when it's in a webview, it loads the arcgis files through script tag in file:// instead of http://
My code is based on your example :
https://github.com/tomwayson/esri-angular-cli-example
Hi Tom,
first of all I want to say thanks to you for all of your work.
I follow exactly your guide to add esri map to my angular4 project, but here my result:
No error in console....so I don't understand why this happening.
Following my specs:
"@angular/cli": "^1.2.3", "@angular/compiler-cli": "4.0.2", "@types/arcgis-js-api": "^3.21.0", "angular-esri-loader": "^1.1.0", "esri-loader": "^1.1.0", "typescript": "~2.0.3"
I'll try with a clean new angular 4 app and I let you know.
Have you ever found this issue?
I get an error message of [Cannot read property 'setTransform' of undefined]. The code and err picture as below. The same code can work fine in arcgis javascript api sandbox but not in angular cli project.
import { Component, OnInit } from '@angular/core'; import { EsriLoaderService } from 'angular-esri-loader'; @Component({ selector: 'app-demo', templateUrl: './demo.component.html', styleUrls: ['./demo.component.css'] }) export class DemoComponent implements OnInit { map: __esri.Map; mapView: __esri.MapView; constructor(private esriLoader: EsriLoaderService) { } ngOnInit() { return this.esriLoader.load({ url: 'https://js.arcgis.com/4.3/' }).then(res => { this.esriLoader.loadModules([ 'esri/Map', 'esri/views/MapView', 'esri/layers/FeatureLayer', 'esri/renderers/SimpleRenderer', 'esri/symbols/SimpleMarkerSymbol', 'esri/Color', 'esri/tasks/QueryTask', 'esri/tasks/support/Query', 'esri/geometry/SpatialReference', 'esri/layers/GraphicsLayer', 'esri/Graphic', 'esri/geometry/Point', 'esri/layers/Layer' ]).then(([Map, MapView, FeatureLayer, SimpleMarkerSymbol, SimpleRenderer, Color, QueryTask, Query, SpatialReference, GraphicsLayer, Graphic, Point, Layer]: [__esri.MapConstructor, __esri.MapViewConstructor, __esri.FeatureLayerConstructor, __esri.SimpleMarkerSymbolConstructor, __esri.SimpleRendererConstructor, __esri.ColorConstructor, __esri.QueryTaskConstructor, __esri.QueryConstructor, __esri.SpatialReferenceConstructor, __esri.GraphicsLayerConstructor, __esri.GraphicConstructor, __esri.PointConstructor, __esri.Layer]) => { this.map = new Map({ basemap: "hybrid" }); this.mapView = new MapView({ zoom: 13, center: [121.521629333494, 25.05335167469987], container: 'map', map: this.map }) var markerSymbol = new SimpleMarkerSymbol({ color: new Color([226, 119, 40]), outline: { // autocasts as new SimpleLineSymbol() color: new Color([255, 255, 255]), width: 2 } }); this.mapView.on('click', evt => { let gc = new Graphic({ geometry: evt.mapPoint, symbol: markerSymbol }); this.mapView.graphics.add(gc); console.log(evt.mapPoint); }); }); }); } }
After all the pain and suffering that I went through trying to initially publish library in way that it could actually be consumed in an Angular app, there are now actually a few good resources on how to properly publish an angular library:
https://medium.com/@cyrilletuzi/how-to-build-and-publish-an-angular-module-7ad19c0b4464
http://blog.mgechev.com/2017/01/21/distributing-an-angular-library-aot-ngc-types/
UPDATE: See below for final punch list
Things I'm sure I want to do:
Things I'm not sure are needed, nor how beneficial they are for a library that only exposes a service:
Prob could use angular2-esri4-components as a starting point if going w/ ngc and module.
Also not sure if this sentence from the medium article: "explicit "paths" to other modules you use are needed, as the final bundle won’t include them directly (more on that later)." which refers to these lines would apply to esri-loader.
I am using angular 4 and add esri map with angular-esri-loader
Everything works fine in Chrome and Firefox. But in IE11, I cannot click and drag mouse to pan map.
Here is my component typescript code
import {Component, OnInit, ViewChild, ElementRef} from '@angular/core';
import { GlobalService } from '../../services/global.service';
import { EsriLoaderService } from 'angular-esri-loader';
@Component({selector: 'app-map', templateUrl: './map.component.html', styleUrls: ['./map.component.scss']})
export class MapComponent implements OnInit {
@ViewChild('mapNode') mapEl: ElementRef;
constructor(private esriLoader: EsriLoaderService) {}
ngOnInit() {
this.esriLoader.load({
// use a specific version of the API instead of the latest
url: '//js.arcgis.com/3.21/'
}).then(() => {
// load the map class needed to create a new map
this.esriLoader.loadModules(['esri/map']).then(([Map]) => {
// create the map at the DOM element in this component
var map = new Map(this.mapEl.nativeElement, {
center: [-118, 34.5],
zoom: 8,
basemap: 'dark-gray'
});
});
});
}
}
Here is my html
<div #mapNode></div>
Here is my packages.json
{
"name": "angular",
"version": "0.0.0",
"license": "MIT",
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e"
},
"private": true,
"dependencies": {
"@angular/animations": "^4.0.0",
"@angular/common": "^4.0.0",
"@angular/compiler": "^4.0.0",
"@angular/core": "^4.0.0",
"@angular/forms": "^4.0.0",
"@angular/http": "^4.0.0",
"@angular/platform-browser": "^4.0.0",
"@angular/platform-browser-dynamic": "^4.0.0",
"@angular/router": "^4.0.0",
"classlist.js": "^1.1.20150312",
"core-js": "^2.4.1",
"intl": "^1.2.5",
"rxjs": "^5.1.0",
"web-animations-js": "^2.2.5",
"zone.js": "^0.8.4",
"angular-esri-loader": "^1.1.0"
},
"devDependencies": {
"@angular/cli": "1.2.1",
"@angular/compiler-cli": "^4.0.0",
"@angular/language-service": "^4.0.0",
"@types/jasmine": "2.5.45",
"@types/node": "~6.0.60",
"codelyzer": "~3.0.1",
"jasmine-core": "~2.6.2",
"jasmine-spec-reporter": "~4.1.0",
"karma": "~1.7.0",
"karma-chrome-launcher": "~2.1.1",
"karma-cli": "~1.0.1",
"karma-coverage-istanbul-reporter": "^1.2.1",
"karma-jasmine": "~1.1.0",
"karma-jasmine-html-reporter": "^0.2.2",
"protractor": "~5.1.2",
"ts-node": "~3.0.4",
"tslint": "~5.3.2",
"typescript": "~2.3.3"
}
}
Any help or suggestion is appreciated.
Thanks
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.