Ember with ArcGIS API for JavaScript
I’m a person that likes to try new frameworks and toolets. Even when I was doing Flash development, I really enjoyed using Swiz and Robotlegs, and with JavaScript, aside from the staples of jQuery and Dojo I’ve enjoyed Backbone, Knockout, Angular, React and much more. Some of these tools tend to be a little easier to use than others. One that has always eluded me though, was Ember. I don’t know if I could pinpoint exactly what about Ember I had always found difficult to grasp. After all, I figured out how to write Angular Directives, so it should be a walk in the park. Maybe my difficulties with Ember have been the idea that Ember is really opinionated. There is definitely an Ember way of doing things, but I’ve come to find that this rigid structure of the Ember way of doing things is one of its greatest strengths. Especially working with a team of developers, it’s really nice to know that everyone is doing things the same way.
Most recently, over the past couple of months, one of the things that helped Ember click is Ember-cli. Ember-cli is like Yeoman on steroids for Ember. It will scaffold your entire application, including your tests for you. To really see some of this in action, check out this video on TDD with Ember-cli. I got up to speed using the ember-cli 101 book and most recently Deliver Audacious Web Apps with Ember 2. At this point, Ember and Ember-cli are working in unison and it is highly recommended to use Ember-cli when doing Ember development.
Sounds great, let’s get started
So once I felt pretty comfortable with Ember and Ember-cli itself, I was pretty excited to dive right in and use it with my ArcGIS API for JavaScript development. Then I got smacked in the face with a brick. It doesn’t work. You can use vanilla Ember with the ArcGIS JS API like you would most other frameworks, but not when using the Ember-cli. Without getting into too many details, it boils down to Ember-cli using a minimal synchronous amd loader versus an asynchronous AMD loader such as RequireJS or Dojo loader. The default loader for Ember-cli is loader.js. So I set out to try many, many, different ideas on how to get everything to work together. A fella named Jack Rowlingson sent me a pretty cool idea on how to get this to work. There also seemed to be some other interest on using AMD with Ember-cli, so I knew I wasn’t alone in this task. Thus was born the ember-cli-amd addon.
Just add it on
Feel free to go through the source code for the details of how this works. There are a couple of ways you could use this addon. You could use RequireJS as the loader or you could point to a CDN loader. If you decided to install AMD modules using RequireJS and bower install AMD libraries, the addon will compile your AMD modules using the RequireJS Optimizer. This actually works out pretty fast as you write your code.
Here is a sample of what your configuration would look like. gist
In this case, I am providing a srcTag pointing to the ArcGIS JS API CDN. This will use the Dojo AMD loader to start the application. With this option you need to at least provide the amdPackages option, which tells the addon which root modules to look for and load as AMD modules. It will then inject these modules into the loader.js used by Ember-cli.
A similar option is to bower install requirejs. Set useRequire to true, provide the amdPackages and if you want, provide a RequireJS configuration for the optimization settings.
Then you need to modify the index.html and tests/index.html files with some content-for blocks. gist
If you happen to need it, you can bower install dojo and set useDojo to true and this will inject the Dojo loader into your application.
Ember fun times
So, let’s build a simple app using the ArcGIS JS API CDN. Once you have Ember-cli installed and ready to go, run this command from the command-line of your choice (it’s called ember-cli for reason).
ember new ember-esrijs
Let it do it’s thing and navigate into the directory for your project. At this point you can go ahead and run this command.
npm install —save ember-cli-amd
Awesome, you have the addon installed. Update the index.html as we described above. You’ll also want to update your Brocfile.js as shown here. gist In this case, I know I am going to use Dojo via the CDN, so I will set up the dojoConfig.
Now let’s create some components.
ember generate component esri-map ember generate component esri-search ember generate component esri-legend ember generate component map-switch
Ember-cli will scaffold your components for you. Let’s fill out our components now, here’s the esri-map. gist As you can see, Ember-cli uses es6/es2015. Learn it, live it, love it.
Here’s is the search component. gist
Here is the legend component. gist
Then we have a small component that will switch the maps. gist
These Ember components are very similar to WebComponents and it’s a good way to think of them like that. In this application, we’ll add an index.hbs into app/templates/index.hbs. gist Ember uses Handlebars or it’s DOM templates, so it’s pretty easy to set up the layout of your DOM in here. At this point, you just need to set up the styling for your app and you should be good to go. You can now run your application.
ember serve
Go to http://localhost:4200
and you’re good to go!
You can find a sample of this application on github.
That’s it
As you can see, the Ember-cli really makes scaffolding your application pretty simple. Once you get into routing Ember-cli will even update your Router for you, so it’s a great tool you can use to quickly get applications up and running. If you have had issues trying to use AMD libraries, or embed your Ember-cli app in a RequireJS application, give the ember-cli-amd addon a try.
I’m still learning some detailed Ember bits. I wouldn’t call myself an expert just yet, but I’m working on it. I did learn a lot about writing Ember-cli addons and broccoli, which is a dependency of Ember-cli. This subject alone probably warrants it’s own post.
I would highly recommend any developer give Ember-cli a try. It may be opinionated, but it has some pretty good opinions.