Well, this is embarrassing. There should be an image here. Great picture, too!
Angular2 Lessons Learned

What is This?

During my first week or so at IBM Watson, the UI team was working out whether to use React.js or Angular2. The design specification wasn't quite agreed upon yet so I had a chance to play around with tutorials for both.

Even though the team ended up not using Angular2, it was a good learning experience for me, as I had previously never written an Angular2 web application from scratch. I'm writing up what I learned here so that I can look back on it as a refresher and maybe so I'll get some views to my website.

File Structure and Setup

How Does Angular2 Setup Differ From Setup for a Static Page?

Most UI developers (myself included) are most familiar with the simple static page. You have:

index.html
style.css
script.js

And you can open your website without any back-end: no server needed! You just open up the index.html file using your file explorer as you would any other file; your browser finds the local .css and .js files you pointed to and you're on your way.

Things aren't so clean with an Angular2 application, but it still comes down to html, css, and JavaScript doing their thing in the browser. The difference is that Angular2 is written in TypeScript and refers to a lot of Angular-specific keywords and objects. So even though we write Angular2 code in TypeScript, it still needs to be compiled into JavaScript before a browser can run it.

What's the Actual File Structure?

You will find a more complete explanation, complete with examples in the official quickstart docs. Here is my intuitive understanding of how the pieces fit together.

project-folder/
  + package.json (optional)
  + tsconfig.json
  + typings.json (optional)
  + systemjs.config.js
  + app/
     + app.component.ts
     + main.ts
     + index.html

The pre-requisite files are pretty long and I must admit I would be lost without the official docs for how to get a local setup running. The nice part is that once you have your workflow up, you can mostly ignore all these files.

  • package.json: Since there are a lot of external packages required to make Angular2 run, it's recommended to use a package manager to keep them all up-to-date. Google recommends npm, hence the package.jsonfile. Using npm has the consequence of creating a possibly-huge node_modulesfolder that is required for your code to run. Personally, I like to use CDNs where possible so this was an adjustment for me.
  • tsconfig.json: is just a JSON object that tells your compiler how you have written your TypeScript and what kind of JavaScript you would like it to compile into.
  • typings.json: provides pointers to the TypeScript definition files. These are files that help the compiler to understand cutting-edge syntax that hasn't made it into the compiler quite yet. It's necessary in the short term but as TypeScript and Angular2 mature, cutting-edge syntax will be widely supported.
  • systemjs.config.js: takes care of loading modules from node_modules/ and elsewhere rather than having you explicitly include them inside the head tags of your index.html.

Here's the part that you'll find more familiar: the actual application folder.

  • index.html: this is a normal html file and will be run as such. The Angular Quickstart recommends a file structured this way. The notable part is where script tags run systemjs.config.js. When you open index.html, it runs systemjs.config.js which runs main.ts, which in turn runs app.component.ts. Finally, app.component.ts replaces the <my-app> selectors with your actual app. It's a real team effort.
    <html>
      <head>
        <title>Angular 2 QuickStart</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="stylesheet" href="styles.css">
    
        <!-- 1. Load libraries -->
         <!-- Polyfill(s) for older browsers -->
        <script src="node_modules/core-js/client/shim.min.js"></script>
        <script src="node_modules/zone.js/dist/zone.js"></script>
        <script src="node_modules/reflect-metadata/Reflect.js"></script>
        <script src="node_modules/systemjs/dist/system.src.js"></script>
    
        <!-- 2. Configure SystemJS -->
        <script src="systemjs.config.js"></script>
        <script>
          System.import('app').catch(function(err){ console.error(err); });
        </script>
      </head>
    
      <!-- 3. Display the application -->
      <body>
        <my-app>Loading...</my-app>
      </body>
    </html>
        
  • main.ts: The job of main.ts is to import the app.component.ts file and bootstrap it with a special imported function. It's pretty short and you could put these lines in with app.component.ts but it's good to keep this logic in a separate file.
    import { bootstrap }    from '@angular/platform-browser-dynamic';
    import { AppComponent } from './app.component';
    bootstrap(AppComponent);
  • app.component.ts: This is the root component of your application. As you build out the app, you will include references to other components inside the template with html tags such as <my-child-selector></my-child-selector>. Those other components typically live in separate files, so you can include them with import lines like the one at the top of the snippet. Once you have application logic, you include methods inside the empty class at the bottom. It looks like this:
    import { Component } from '@angular/core';
    
    @Component({
      selector: 'my-app',
      template: `<h1>My First Angular 2 App</h1>
                 <my-child-selector></my-child-selector>`
    })
    
    export class AppComponent { }

And there you have it. All the file setup required to get your "hello, world" Angular2 app running!

If you follow the file setup in the quickstart (which is the same file setup I am following here) you will be instructed to call npm start to set up a static file server. If, like me, you don't like the idea of being tied down to a running server, you can get it all to run just by opening index.html. The trouble is that the code as-is references a lot of files at the root of the file system rather than the root of the project. Just modify the references and you will be good to go.

Impressions of Angular2

I can see the power of a front-end framework in general. It separates out components with a focus on re-usability. In a large codebase that is absolutely vital too keeping it organized and structured.

The complexity of Angular2 seems excessive in certain areas. I felt very limited when I would write a function and need to package it as a service before using it in a different context. I also found myself needing to draw diagrams and delve into much more background to understand how to add relatively basic features to the pre-canned tutorial.

At least for the moment, Angular2 is a "walled garden". It is written in TypeScript, which is super cool, but it actively forced me to do things "the Angular way". When I tried to implement a feature that would trigger on right arrow, I soon found myself delving into the Angular2 source code to see whether that particular event binding had been implemented yet (it hadn't been at the time, June 2016). Maybe there was a way to use the native JavaScript onkeyup event but I had enough trouble finding out how that I gave up on the feature.

Built-in features are nice, of course. ng-if and ng-for were definitely useful in my previous job at Biztera but I never fully got a grasp of the bigger picture even though I was editing a lot of individual components. Of course, part of that reflects on me, but after a few weeks using it, I certainly don't have the same challenge with React.js.

In any case, it's enriching to see how other frameworks are developing, and Angular2 is definitely at the cutting edge with TypeScript and other features. I'm glad to have familiarized myself with the framework and would be more than pleased to work with Angular2 in my future projects.

What to Do Now

If you are new to Angular2 I highly recommend going through the Tour of Heroes tutorial. It taught me a lot about the power of separating out components as well as front-end routing. It's neat to switch pages and URLs without ever needing to refresh the page. It also gets into the nitty-gritty of calling services across different files which can be rather confusing.

If you want to see something cute, you can also check out my modified version of the tutorial where I replaced each of the "heroes" with the names of my team in an effort to learn everyone's names.

PS: Sorry in advance if the link becomes dead! The tutorial code has a bug where the node_modules folder takes up a huge amount of space and isn't worth hosting on my own server.