DISCOVERY

January 6th, 2018

Angular 5 First Impressions

Angular

TypeScript

JavaScript

HTML

Recently I learned a few JavaScript technologies for building website backends. I looked at Node.js in the server layer and MongoDB in the database layer. Now I'm switching gears and learning some front-end JavaScript technologies. My top two picks for front-end frameworks are Angular and React.js. Today I'm beginning my journey with Angular. Through this research I will determine if its a suitable option for my website. This post won't display much code, instead focusing on my initial reactions to the framework.

Getting started, I struggled for a very long time setting up all my Angular dependencies. I wanted to do it all manually in the beginning so I could get to know the framework better. I tried and failed for a few hours and eventually gave up. The problem was my Angular "hello world" code returned a blank screen with no error messages (which is quite hard to debug). I decided that I was in over my head with this framework and had to choose an easier entry approach.

Luckily there is an easier option - the Angular CLI. Angular CLI automates many common tasks in the Angular framework. It builds new Angular projects, creates new components, runs Angular code on a server and more1. The Angular CLI is also a wrapper around Webpack, performing all the module bundling for you2. I don't yet know the details of Webpack, so auto bundling makes Angular CLI really helpful. Once I really understand the ins and outs of Angular, it may be nice to have more control over a project than Angular CLI gives me.

The nicest thing about Angular CLI is how easy it is to setup a new project. After Angular CLI is installed, creating and running a new Angular project is as easy as the following two Bash commands.

# Create a new Angular project with name 'developer' ng new developer # Start the Angular project on a server ng serve

The one thing that annoyed me about Angular CLI is how much content they put into the base Angular project. The bloat included fully set up testing suites (multiple), a fully populated .gitignore file, and more. For someone who likes to customize my own project, this was overkill. I ended up deleting most of these files to get only the necessary components.

The creators of Angular suggest that you use TypeScript, a superset of JavaScript that is statically typed. You can also use JavaScript, but I've decided to follow the advice and try TypeScript. So far I've found it to be more detrimental than beneficial.

Supposedly TypeScript is a true superset of JavaScript, meaning all JavaScript code is valid TypeScript code. However, in my first hacks at the language I had trouble using JavaScript features in TypeScript. For example, when using a RegExp in TypeScript I got errors saying that its JavaScript functions did not exist. This may be simply user error, but so far TypeScript has not been the smooth transition it is advertised to be.

Also, using TypeScript disrupts my full JavaScript web stack. Although TypeScript is very similar to JavaScript, I still have to adjust to using two different languages when developing. As my TypeScript experience grows I will see if I start seeing some benefits of the language.

This post has been fairly negative, so I will take a break from that and look at some exciting things about Angular that I can't wait to get my hands on. Angular at its core is made up of modules that contain components, directives, services, etc3. When working with AngularJS I always liked the modularized structure it gave my JavaScript code in comparison to my old JQuery spaghetti code. Angular 5 seems even more modularized then AngularJS, which appears beneficial at first glance.

My "hello world" Angular project contains one module. It is exported for use in other classes.

import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { DeveloperComponent } from './app.component'; import { ValidDevDirective } from './valid-dev.directive'; // Wrap a component and directive into a module. // Each file can be one module which can be exported. // You must import BrowserModule in the root module @NgModule({ imports: [BrowserModule], declarations: [DeveloperComponent, ValidDevDirective], bootstrap: [DeveloperComponent] }) export class AppModule { }

The @NgModule annotation specifies that this class is an Angular module. Note that just like ES6 classes, TypeScript classes are not true classes. They are transpiled into JavaScript prototypes and are simply syntactic sugar.

The annotations object has a declarations property that specifies all the members of the module4. The first module member is a Component named DeveloperComponent. Each component has a TypeScript class that defines model data and a view (which is usually HTML).

import { Component } from '@angular/core'; // Create a new Angular component which can be used in HTML with the 'developer' tag // Angular uses annotations as metadata @Component({ selector: 'developer', templateUrl: 'app.component.html' }) export class DeveloperComponent { dev: string; constructor() { this.dev = 'Andy'; } }

The awesome thing about components is they define a reusable HTML tag. Each HTML tag is named after the @Component annotations selector property. The contents of a HTML tag are defined in the @Component annotations template or templateUrl properties. The HTML contents render on a webpage at runtime, replacing the components HTML tag.

For example my code has an index.html file like so:

<body> <developer></developer> </body>

When rendered in the browser, the <developer> tag is replaced with the markup defined in my component:

<div> <h1> Hello {{ dev }}! </h1> <p>Enter a developer name:</p> <div> <input type="text" name="devInput" valid-dev> </div> </div>

The characters {{dev}} in the HTML document are replaced with the dev variables value in the DeveloperComponent class. This binding between HTML and TypeScript creates many possibilities for dynamic webpages that I can't wait to explore!

The second module member is a directive called ValidDevDirective. A directive is like a component except it has no view and is placed on an existing HTML element 5. If you look at the HTML input element in my component above you will see an attribute called valid-dev. This attribute is defined in my directive, which right now changes the border color of the input field when a value is entered.

import { Directive, ElementRef, Renderer2 } from '@angular/core'; @Directive({ selector: 'input[valid-dev]', host: { '(input)': 'onInput($event)' } }) export class ValidDevDirective { renderer: any; element: any; constructor(renderer: Renderer2, element: ElementRef) { this.renderer = renderer; this.element = element; this.style('#ccc') } // When the value in the input field changes, check its contents onInput(event) { let value: string = event.target.value; if (value === '') { this.style('#ccc') } else { this.style('black') } } style(color) { this.renderer.setStyle(this.element.nativeElement, 'border-color', color) } }

This is a very trivial implementation, but it is cool how directives extend the implementation of HTML elements. Reusable directives and components save time and lines of code throughout a project. Like components, I am excited to try out more complex directive implementations.

This was a quick glance at my first attempts with Angular 5. I am not convinced Angular is the solution for me yet, but there is still a lot of work and exploring to do. Up next I will start building a full Angular project!

[1] "The Ultimate Angular CLI Reference Guide", https://www.sitepoint.com/ultimate-angular-cli-reference/

[2] "To use Angular CLI or not?", https://medium.jonasbandi.net/to-use-angular-cli-or-not-187f87d0b550

[3] Yakov Fain &amp; Anton Moiseev, Angular 2 Development with TypeScript (Shelter Island, NY: Manning, 2017), 32

[4] Ibid., 33

[5] Ibid., 35