Getting Started with Angular
Prologue
In one of my previous jobs, I used Angular 2 (and later versions) to build from scratch the front-end for a complete full-stack application. I loved the simplicity of Angular components, the elegance of one-way and two-way bindings, scoped CSS, and the power of TypeScript.
Here I revisit the basics, which is really important to eliminate the "activation-energy" needed to start a new project. The official documentation is great, and I urge you to read it, but reading different perspectives (such as this post) can help you understand things better. This one is for beginners to Angular, or those who need a quick refresher.
Prerequisites
I will be using the latest 64-bit versions of Visual Studio Code (1.20.1), Node (10.13.0) and Angular (7.0.0) at the time of writing. This version of Node comes with version of 6.4.1 of Node Package Manager (NPM).
Download links
- VS Code If asked, check the "automatically install the necessary tools" checkbox during install. Note: This might force reboot your machine multiple times.
- Node.JS
Starting Up
Only 4 simple commands are all it takes to get going:
npm install -g @angular/cli # globally install the ng command
ng new angular-starter # create a new project
cd angular-starter
ng serve # starts HTTP server and file watcher
In the second command, Angular will:
- Ask you to have Angular routing (I selected yes) and
- Choose to have a stylesheet format (I selected LESS - that rhymes).
LESS
is a CSS compiler, and so are the other options SASS
and SCSS
. They are similar, but LESS is JavaScript based, wheras SCSS is Ruby based. SASS is an older version of SCSS.
In the 4th command, Angular will start an HTTP server at port 4200. On Windows, this can bring up the Windows Firewall security dialog. (I allowed Node to access the network for both private and public networks.) It also starts watching file changes, to continuously build and serve the most updated files.
The server by default can be accessed via http://localhost:4200/
.
Creating Your First Component
A component allows you to, well componentize, parts of your user-interface so they can be reused in multiple places. To see how this works, let's create a simple component.
In the root folder of your project do:
ng g component list-of-links
This will do a few things:
- Create a new folder called list-of-links under src/apps
- Create the HTML, Less, TS and Spec.TS files in that folder
- Import your component in
app.module.ts
and make it part of the module by including it in thedeclarations
array.
Your component can now be referenced in any HTML file using its
selector
defined in the TS file. By default, components get theapp-
prefix, which you can configure using theprefix
field inangular.json
.
Next, do the following:
- Cut the HTML section defined by the
<ul>...</ul>
tags fromapp.component.html
. - Put in
<app-list-of-links></app-list-of-links>
where theul
tags used to live. - Paste what you cut into
list-of-links.component.html
. - Save all files and check
http://localhost:4200
to see that the list is still shown. - If there are any issues, use the Developer Tools in your browser and check any error messages in the console.
The component here is completely static. To make it dynamic, we can create bindings
to variables of the view's class.
In the component's TS file, create a class member as follows:
items = [
{ href: "https://angular.io/tutorial", label: "Tour of Heroes" },
{ href: "https://github.com/angular/angular-cli/wiki", label: "CLI Documentation" },
{ href: "https://blog.angular.io/", label: "Angular blog" }
];
Edit the component's HTML file to have only the following:
<ul *ngIf="items?.length">
<li *ngFor="let item of items">
<h2><a target="_blank" rel="noopener" [href]="item.href">{{ item.label }}</a></h2>
</li>
</ul>
While functionally the same as before, this change allows our component to display an arbitrary number of links defined in the list. In a real-world application, the data would be retrieved from a web service.
Let's look at this new syntax in detail.
- In the
ul
element, *ngIf evaluates the expression to determine whether its element should be included in the view. Here we're using the null-coalescing operator, which is shorthand for items && items.length. If items is undefined or is empty, this section will be skipped completely. - In the
li
element, *ngFor is indicating that we want an instance of this element for each item in the items array (or none if items is empty). Theof
keyword is important here. - In the
a
element, the square brackets aroundhref
is indicating that its value should be one-way bound to the expressionitem.href
. Item takes on the value of each object as Angular iterates over the items array. - The double curly brackets around
item.label
is also a one-way binding.
If using one-way binding for an HTML attribute, use square brackets around the attribute name. If using one-way binding for HTML content, use double curly brackets around the expression.
It's also possible, and very simple, to do two-way binding for input controls such as the input box. The syntax for this is [(attribute)]="field"
. This is really a shorthand. An equivalent, albeit not as elegant, appriach is to set up the one-way binding in one direction, and define an event handler for the opposite direction: [attribute]="field" (attributeChange)="field=$event"
. Change prefix is used by convention. $event is an important keyword that denotes the argument passed to the component's EventEmitter
's emit
method, which then calls our event handler. The event handler is defined inline and sets the field to the new value.
Note that the value side of a two-way binding cannot be an expression: it has to be a field or a property of the class. The field or the setter of that property should be decorated with @Input()
.
This is just the tip of the iceberg, but should cover enough ground to get you going. Make sure to check out my next post Key Concepts in Angular, which would have been part of this post had it been not so long.