You are on page 1of 62

Choosing the Best

JavaScript Framework for You


Rene Rubalcava (@odoenet) & Raul Jimenez (@hhkaos)
github.com/odoe/presentations
The JS framework MADNESS

Do I even need a framework??


Timeline: JS Frameworks & Libraries
Trends: Interest over time
Trends: 2004 - 2016
So the quick answer is...
Conservative Hipsters

jQuery React / Angular


Beyond the cool-factor

How is the learning curve?


Evaluating a framework
Documentation
Features (pros & cons)
Performance / weight / ...
Programming style (MVC, event-driven, ...)
Major version changes
Dependencies: AMD vs. Browserify vs. Nothing
Stability? (3rd party sponsorship)
Angular & Google, Dojo & Esri, ...
The community
Stackoverflow questions
For those hosted on Github:
Number of contributors
Number of open & closed issues
Number of open pull requests
Lastest commit date
Project & team
Do not forget the most important thing!:
New project or expanding existing project?
Your project expected lifetime? (pilot, large project, ...)
Your project size? (small, medium, large, ...)
Do you have existing build system?
Or existing frameworks?
Your team skill sets?
Your project requirements?
Github projects
To build nice apps with ArcGIS API for JS 3.X:
angular-esri-map-v1
esri-leaflet
calcite-maps (Bootstrap)
angular-esri-map-v1
<esri-map id="map" map-options="map.options">
<esri-vector-tile-layer
url="//www.arcgis.com/sharing/rest/content/items/bf79e422e9454565ae0cbe9553cf6471/re
</esri-vector-tile-layer>
</esri-map>

View live demo


esri-leaflet
var map = L.map('map').setView([45.526, -122.667], 15);
L.esri.basemapLayer('Streets').addTo(map);

L.esri.Cluster.featureLayer({
url: 'https://services.arcgis.com/rOo16HdIMeOBI4Mb/arcgis/rest/services/Trimet_Transit_Sto
}).addTo(map);

<link rel="stylesheet" href="path_to_source/leaflet.css" />


<link rel="stylesheet" href="path_to_source/MarkerCluster.Default.css">
<link rel="stylesheet" href="path_to_source/MarkerCluster.css">
<!--
scripts:
- leaflet-src.js (L)
- esri-leaflet@2.0.6 (L.esri)
- leaflet.markercluster.js (L.markercluster)
- esri-leaflet-cluster@2.0.0 (L.esri.Cluster)
-->

View live demo


calcite-maps
<body class="calcite-maps calcite-nav-top">

<nav class="navbar calcite-navbar navbar-fixed-top calcite-text-light calcite-bg-dark calc


<div class="calcite-title calcite-overflow-hidden">
<span class="calcite-title-main">Map Title</span>
</div>
</nav>

<div class="calcite-map calcite-map-absolute">


<div id="mapViewDiv"></div>
</div>

</body>

View live demo


Options available to you
Templates
Configurable Apps
Apps
Builders
App Studio
Web AppBuilders
Templates
Easy to use
Configurable
Integrates with Portal
Apps
Prebuilt with specific purpose (Collector, Navigator)
Some provide extensibility (Ops Dashboard)
Web AppBuilder
Can be thought of as its own framework
jimu - the Lego framework
You need more?
Or do you want more?
Dojo can do the job
Dojo already did that
[JSConfUS 2013] Peter Higgins: #dadt (Dojo already did ...
Framework Madness
What problems do they solve?
Common theme is Web Components
Web Components are not standardized yet
Some data binding mechanism
What makes 4.x easier to use?
Accessors
View Models (crème de la crème)
Maps and Views (SceneView, MapView)
React
React
Not a framework
Reusable, composable components
JSX - declarative
const view = new MapView({
container: document.getElementById('viewDiv'),
map,
center: [-100.33, 25.69],
zoom: 10,
ui: { components: [] } // empty the UI
});
// Render the React Components
ReactDOM.render(
<div>
<Zoom view={view}/>
<Attribution view={view}/>
<BasemapToggle view={view} secondaryBasemap={'dark-gray'}/>
</div>,
document.getElementById('appDiv')
);
React
Demo
Angular 2
Angular 2
Directives are Web Components
Dependency Injection
RxJS 5
import { Component } from 'angular2/core';
import { MapComponent } from './map.component';
import { HomeComponent } from './home.component';
@Component({
directives: [MapComponent, HomeComponent],
selector: 'my-app',
template:
`
<div>
<esri-map #mapView (viewCreated)="homeButton.setView(mapView.view)">
<esri-home #homeButton></esri-home>
</esri-map>
</div>
`
})
export class AppComponent { }
Angular 2
Some challenges
Uses SystemJS Module Loader
Well that's not going to work for us
System.import('./local-module.js');

System.import('https://code.jquery.com/jquery.js');
Angular 2
Don't fight the loader, work around it
Angular 2
function register(name: string, mods: any[]) {
System.register(name, [], exp => {
return {
setters: [],
execute: () => {
mods.map((mod: any, idx: number) => {
exp(moduleName(deps[idx]), mod);
});
}
}
});
}
require(['esri/Map', 'esri/views/MapView'], function(...modules) {
register('esri-mods', modules);
System.import('app/boot');
});
Packaged it up for you
esri-system-js
esriSystem.register(
// array of Esri module names to load and then register with SystemJS
[
'esri/Map',
'esri/views/MapView',
'esri/widgets/Home/HomeViewModel',
'esri/request'
],

// optional callback function


function() {
// then bootstrap application
System.import('app/boot')
.then(null, console.error.bind(console));
});
Angular 2
Angular 2
Demo
Ember
Ember
The Ember Way
Ember way or get out the way!
Focus on Web Components
ember-cli
Robust add-on system
Ember
Also had some challenges
Uses it's own synchronous AMD-like loader
Doesn't like RequireJS or Dojo loaders
Ember
So we wrote an addon to help with that
ember-cli-amd
Ember
ember install ember-cli-amd
var EmberApp = require('ember-cli/lib/broccoli/ember-app');
module.exports = function(defaults) {
var app = new EmberApp(defaults, {
amd :{
loader: 'https://js.arcgis.com/4.2/',
configPath: 'config/dojo-config.js',
packages: [
'esri','dojo','dojox','dijit',
'put-selector','xstyle','dgrid'
]
}
});
return app.toTree();
};
Ember
Map as a service
// app/services/map.js
export default Ember.Service.extend({
map: null,
loadMap() {
let map = this.get('map');
if (map) return map;
let graphicsLayer = new GraphicsLayer({ id: 'graphics' });
let tileLayer = new VectorTileLayer({
url: "https://www.arcgis.com/sharing/rest/content/items/f96366254a564adda1dc468b447ed9
});
map = new Map({ layers: [tileLayer, graphicsLayer] }); // no display
this.set('map', map);
return map;
}
}
});
Ember
Map component
//app/components/esri-map.js
export default Ember.Component.extend({
classNames: ['viewDiv'],
mapService: Ember.inject.service('map'),
didInsertElement() {
let map = this.get('map');
if (!map) {
map = this.get('mapService').loadMap();
this.set('map', map);
}
},
createView: function() {
let map = this.get('map');
let view = new MapView({
map,
container: this.elementId,
center: [-100.33, 25.69],
zoom: 10
});
view.then(x => this.set('view', x));
}.observes('map') // similar to Accessor.watch
});
Ember
Using a ViewModel
// app/components/esri-home.js
import Ember from 'ember';
import HomeVM from 'esri/widgets/Home/HomeViewModel';
export default Ember.Component.extend({
classNames: ['home', 'action'],
vm: null,
createHome: function() {
let view = this.get('view');
let vm = new HomeVM({ view });
this.set('vm', vm);
}.observes('view'), // similar to Accessor.watch
actions: {
enable() {
this.get('vm').goHome();
}
}
});
Ember
Compose your components
//app/templates/index.hbs
{{esri-map view=view}}
{{esri-locate view=view}}
{{esri-home view=view}}
Ember
Demo
VueJS
doc
VueJS
Focus on components
Not a big learning curve
Virtual DOM
VueJS
// Create a Vue component
Vue.component("camera-info", {
props: ["camera"],
template: "<div>" +
"<h2>Camera Details</h2>" +
"<p><strong>Heading</strong>: {{ camera.heading.toFixed(3) }}</p>" +
"<p><strong>Tilt</strong>: {{ camera.tilt.toFixed(3) }}</p>" +
"<p><strong>Latitude</strong>: {{ camera.position.latitude.toFixed(2) }}</p>"
"<p><strong>Longitude</strong>: {{ camera.position.longitude.toFixed(2) }}</p>"
"</div>"
});
VueJS
view.then(function() {
var info = new Vue({
el: "#info",
data: {
camera: view.camera
}
});
view.ui.add(info.$el, "top-right");
view.watch("camera", function() {
info.camera = view.camera;
});
});
esri-loader
Load Esri modules in a non-AMD environment
repo
esri-loader
// import the esri-loader library
import * as esriLoader from 'esri-loader';

// has the ArcGIS API been added to the page?


if (!esriLoader.isLoaded()) {
// no, lazy load it the ArcGIS API before using its classes
esriLoader.bootstrap((err) => {
if (err) {
console.error(err);
}
// once it's loaded, create the map
createMap();
}, {
// use a specific version instead of latest 4.x
url: 'https://js.arcgis.com/3.18/'
});
} else {
// ArcGIS API is already loaded, just create the map
createMap();
}
Conclusion
4.x Enhancements make integration easier
Pick a framework and dig in
Learn your tools
Tons of resources 1/5
Similar talks already recorded:
2016 Video - Using Frameworks with the ArcGIS API for JavaScript
2015 Video - Picking a JS Framework
2014 Video - Working with Frameworks & ArcGIS API
Angular | Follow: @tomwayson & @jwasilgeo & @dbouwman
2015 Video: Declarative Mapping Applications with AngularJS
Directives to help you use Esri maps and services in your Angular apps
Esri-playground: Angular 2 & Esri 4
Ionic app demonstrating how to use the Esri ArcGIS API for JavaScript
Tons of resources 2/5
Leaflet | @jgravois & @patrickarlt
2015 Video - Esri Leaflet: An introduction
2015 Video - Esri Leaflet: Advanced Topics
2015 Video - Extend Esri Leaflet with Leaflet Plug-ins
Samples with AngularJS, Browserify, drag&drop, RequireJS, etc
15 repos: esri-leaflet, esri-leaflet-geocoder, plugins, ...
A leaflet plugin to display ArcGIS Web Map
Bootstrap | @alaframboise @TheBlueDog | Calcite: @paulcpeterson & @nicolaswise
2015 Video - Bootstrap: Taking Your Mapping UI and UX to the Next Level – PDF
A light-weight JS/CSS extension for to combine Bootstrap with ArcGIS JS (3.x)
How to use our API for JavaScript (3.x) with Bootstap via Dojo-bootstrap
Calcite-maps: A modern framework for designing map apps with Bootstrap
Tons of resources 3/5
jQuery Mobile | Follow: @andygup
Dynamically resizes map when used in multi-view apps
Knockout | Follow: @snydercoder
Video 2015 - Building Map Apps with Knockout and the Esri JavaScript API
DevSummit 2013: Knockout, backbone and Angular samples
Backbone | Follow: @mjuniper
DevSummit 2013: Knockout, backbone and Angular samples
Video 2012 - Have a Little Backbone: An MVC JavaScript Framework for ...
Ember | Follow: @ffaubry & @odoe & @dbouwman
Ember CLI Addon for using AMD libraries
Tons of resources 4/5
React | Follow: @odoe & @tomwayson
EsriJS with React example
Using ErsiJS 4.0 View Models with React
ReactJS demo using BaconJS
Demo app using ReactJS with Esri-Leaflet
How to lazy load the ArcGIS API for JS in a react-router application
Polymer | Follow: @mjuniper
DevSummit 2015: A set of Esri web components built using the Polymer library
DevSummit 2014: Mike Juniper Polymer demo
Tons of resources 5/5
PhoneGap | Follow: @andygup & @lheberlie
2015 Video: Native Apps using PhoneGap+jQuery+ArcGIS – PDF
ArcGIS JavaScript samples for use with PhoneGap/Cordova
Web AppBuilder | Follow: @rscheitlin & @tomwayson & gavinr
Web AppBuilder Developer Resources
CMV | Follow: @tmcgee & @DavidSpriggs
The Configurable Map Viewer - CMV
Resources for the ArcGIS API for JavaScript
Questions?
Help us to improve filling out the survey

Rene Rubalcava (@odoenet) & Raul Jimenez (@hhkaos)


Slides: github.com/odoe/presentations
#

You might also like