Angular Lesson 1

I do not want to repeat anybody else’s Angular For Nimrods-style post, but I do want to digest some of the things I’ve learned over the last few days. I’ve been micro-blogging on Twitter (@adamcrossblog), but that’s not quite good enough. If for nobody else’s sake but my own, I want a coherent summary.

Here are the main differences between me and the average person who might write a book or blog post on Angular. I’m skeptical. I think Angular is and always has been a gigantic hot mess. I began studying Angular (version 2+) only a few days ago, but I’m very familiar with modern techniques using my favorite library, VueJS. Also I’m going to do a lot of contrasting with Vue and complaining about features Vue has that are much more cumbersome in Angular.

I began teaching myself by writing the simplest functioning widget I could think of that actually does something without getting bogged down in details that didn’t interest me at the moment—but I did follow some trails that seems interesting and I’ll comment on those as I go. The first widget was a counter. It starts at zero. There’s a button that increments the value, a button that resets to 0, and a view that shows the current value. Tha end. More on that as we go.

Angular has a command line tool that you can install by executing
npm install -g @angular/cli
. This thing seems to have commands for creating a lot of pre-packaged boilerplate for you. I am the kind of programmer who likes to start with a blank text editor in one window and a command shell in another. So this kind of thing already makes me suspicious. I’m not sure I’ll ever use it again, but I created my first angular app by running the command ng new counter-app. (It’s interactive. I accepted all the defaults except for choosing SCSS over CSS.)

This of course creates an entire directory called counter-app and fills it with SO much stuff. I do remember a time not so long ago when I would have had no idea what it was all for. At this point in my life, however, I at least knew where to start exploring to figure out how this thing works. It’s an npm package. So, everything starts with the package.json file. That config file shows a long list of dependencies and dev dependencies. It also defines some surprisingly terse scripts. For example, the “build” script is defined simply “ng build”. So: what the hell does that do?

This isn’t some detective story I want to drag out, so let me hit some of the highlights now.

This boilerplate app comes pre-configured to use Jasmine, Karma, and Protractor for testing. Jasmine is basically just a unit testing language. Karma actually executes the tests in a live-updating way. It watches for changes in files and re-executes your tests as you work. That’s cool or annoying. I know almost nothing about Protractor. It’s used for end-to-end testing, I think it somehow has Selenium under the hood, and it appears to have been written for and by the angular team.

One unifying theme here is that Angular seems very opinionated about what you should be doing, how you should do it, and—pretty much—that they’re just going to write the code themselves if that is OK.

So in the package.json file, we have a “test” script that is defined simply “ng test”. And there is a lengthy angular.json config file I don’t really understand yet, but I see it has a “test” property buried in there and Karma seems baked in pretty hard for now.

So what does ng build do? Far as I can tell, first there is some kind of Angular-specific pre-compiler that makes sense of all these @decorators that Angular uses and replaces them with actual code. At that point we have TypeScript, so it runs a TypeScript compiler. Then it’s definitely using Webpack to bundle the final JS files. So far I have not looked into details like, say, the transpilation target. I think for now we mostly agree that we transpile to ECMAscript 2015, but I’m sure there is an option buried in here somewhere.

I mentioned the package file lists many dependencies. Some of them I had never heard of. There’s zone.js. What the hell is zone? It actually sounds kinda cool. I found this article: What the Hell is Zone? There’s RxJS, which is a library for processing data streams, but they try to make it sounds like a brand new paradigm we’ve never seen before. There’s something called core-js which appears to be a catch-all polyfill for just everything. More on RxJS later, maybe.

OK then, enough exploration for now. Let’s make a counter. The app is under src/app. The root of everything seems to be a file called app.module.ts. It imports a module AppComponent at the top and then I see a line bootstrap: [AppComponent], so the meaning is clear enough for now. Later I’m going to come back to figure out where this code actually gets read and executed. For now, we take a look at AppComponent.

This is what I see inside the file app.component.ts:

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {
  title = 'counter-app';
}

The way this thing works seems pretty self-explanatory if you have some experience in the area. This is the controller. There is also a file app.component.html containing the template. Right now the template contains useless crap, so I delete all of it and go back to the controller. I’m not actually sure if docs still use that word, “controller”, for this. It’s a class. They are abusing the decorator notation to cram some meta-data in there even though it’s not built into TypeScript. But I assume the template can display data that is public in the class. Stands to reason, right? So I delete that “title” variable and add the line counter: number = 0.

I also want public methods to increment and reset. These two lines should do: increment (): void { this.counter += 1} and reset () : void {this.counter = 0}.

Now in the template I want a view to show the counter and I want an increment button and a reset button. I assume Angular is still using that double-brace notation {{[var]}}, so I’ll throw that in and see if it works. It works. And instead of ng-click on the buttons, now we write something like (click) = "doSomething()" inside the html tag. That part all works as expected.

The Angular command-line tool comes with a server, so you can test interactively by running ng serve --open. It works exactly as expected. It’s super boring, but it works. This and like 5-6 other little design patterns are how web apps are made.

That piece of trite-sounding advice sounds like a good ending line, but I’m so far from done. I have more to say about RxJS and “observables” and computed values and how Angular tries to make everything Java. But I guess I’ll get into that with Lesson 2.

[Update: Angular Lesson 2 is here: https://adamcross.blog/2019/04/21/angular-lesson-2/. This series of tutorials will not be like chapters in a book. the differences from one to the next may be much more profound than that. But they probably are still best read and studied in order.]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s