Wednesday, October 19, 2016

Using Typings' global option with npm run

 In my Angular 2 project using Typescript, I wanted to install typing definitions for OpenLayers. Seems the best way to do this is through Typings Definition Manager (npm install typings). So I run this via npm run typings install dt~openlayers and keep getting the following error:
Attempted to compile "openlayers" as an external module, but it looks like a global module. You'll need to enable the global option to continue.
Easy enough, I'll use the global option!

npm run typings install --global --save dt~openlayers

Nope! Same error! Why?!

Turns out, through npm run, it's trying to parse those options for itself. So to pass the options to typings instead, do this:

npm run typings install -- --global --save dt~openlayers
Note the extra "--" in there!

Monday, October 17, 2016

Angular 2 Route Animation

Angular 2 Animation API is pretty slick. It actually uses the browser's implementation of  W3C Web Animation Specification (or polyfill thereof), but the interface to it from Ng is very clean and easy to use.

You can see some quick examples on their documentation.

But here's how I am using it for animating route changes.

This will allow my side panel to fly in and out on route changes.

What's really important here is the "host" attribute. This will put the animation trigger on the host / containing element ("opscon-menu" in this case) itself. When I put the trigger on any element in the template itself rather on the host, the exit animation ("* => void") never gets executed. This is probably because Angular doesn't have any animation promise when removing the host element, so it just removes it right away. By putting the "@routeAnimation" trigger on the host, Angular waits for the animation to complete before removing the element from the DOM. Note that the name "routeAnimation" has no special significance...  just a name.

As a side note, I'm also attaching a class to the host here. I'm not sure if this is the best spot to do this or not...

Sunday, October 16, 2016

Upgrading to Angular 2 and TypeScript

After all that work using AngularJS (aka Angular 1) and plain ol' JavaScript, I decided to switch over to Angular 2 and TypeScript for this project. Here are a few reasons:
  • This project was still in its infancy so it's a good time to switch.
  • Angular 2 final has just been released.
  • Angular 1, for all its awesomeness, was kindda quirky. It was almost like it wasn't written with JavaScript in mind. That's why I think Angular 2 with TypeScript is a killer combination.
  • Angular 1 is gonna be deprecated sooner than later. You can already sense it in their documentation, particularly when they talk about Components for Angular 1(.5). 
  • I originally thought Angular 2 could compile to native code on mobile seamlessly. This doesn't seem to be quite the case, but it's still a damn good option to have!
  • It's about time I started using TypeScript.

Here are some benefits I'm already experiencing with this new project.
  • Cleaner routes - Working with routes in Angular 2 is a much more pleasurable experience.
  • Animations - ditto
  • Modular - You may have been able to be pretty modular in Angular 1 too, but I feel Angular 2 (and its emphasis on components) combined with TypeScript / ES6 takes it to a whole new level.

One concrete example of the last point about modularity is that I think I am now (easily) able to uncouple our mapping backend!

Originally we were quite set on OpenLayers and pretty opinionated about using it and only it. Giving it some more thought, using the proof-of-concept app, and appreciating the last point above, I came to realize that it doesn't have to be that way. I can expose a common API to the mapping backend and be able to swap OpenLayers out for something else.

This would be useful for an ESRI shop, for example. Yes you can export all ESRI layers in a format for OL to consume, but it would significantly affect one's workflow. Take styling a WFS layer: An ArcGIS Feature Layer would already have all the symbologies built in, while a WFS would not. Being able to use ArcGIS API for JS would be quite an advantage in this case.

I hope to get around to writing an ESRI backend too in the future, but for now I will focus on OL, but will keep in mind to write a solid API for this to happen. Here's how Angular 2 and TypeScript is already allowing me to do just that:


It's a matter of uncommenting a line from a couple of files to swap out the mapping backend! Notice that in the "app.module.ts" it's just abstractingly importing whatever "MapModule" our "map.module.ts" is exporting. We can map "MapModule" to anything!