The CEAN (pronounced “keen”) stack is used to design web apps with a segregated UI (it’s like the MEAN stack, except it uses Couchbase Server).
I’m learning and writing Angular2 for the first time this month, so I thought I would take a moment to blog about what I’ve learned. If you see something I’m doing wrong or suboptimally, now is your chance to give me some feedback and help me learn. You can leave a comment or send me a tweet.
Some quick background: I’ve never used any of these modern UI frameworks in any production code (yet). This includes Angular, Angular2, Ember, React, etc. Where I came from, everything was in JavaScript/jQuery/jQuery UI.
TypeScript Code-behind
You don’t have to use TypeScript to use Angular2, but my coworker Nic Raboy has been using it for a while, and that’s what he’s been guiding me to use.
TypeScript is a superset of JavaScript (think of it kinda like JavaScript++) that gets transpiled to plain JavaScript. In Angular2, a page (or view) is coupled to a TypeScript (ts) file (coming from an ASP.NET background, I think of these as “code-behind files”). The TS file is responsible for loading data that the view can use, as well as responding to events from the view.
A very simple example of a TS file that loads companies from a REST endpoint and makes them available for the view to use:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
import { Component } from '@angular/core'; import { ICompany } from '../../entityInterfaces.ts'; @Component({ selector: 'companies', templateUrl: './app/components/companies/companies.html' }) export class CompaniesComponent { public companies : Array; public constructor() { this.loadCompanies(); } } |
In this example, I’ve “import”ed (this is kinda like a “using” in C#) an interface type called ICompany. That’s right, in TypeScript you can declare types in a much more explicit way than in plain JavaScript. The
in the templateUrl
tells this TS file what HTML file it corresponds to. Finally, I’m creating a class with a constructor and a field called @Component
. The constructor calls a method to load those companies (from a REST endpoint using Ajax). At this point, companies
is available for the HTML file to reference.companies
Angular2 View
An HTML view in Angular2 is mostly HTML, but I think of it as a template. Within this template, I use various Angular2-specific tags and syntax to render something dynamically.
For instance, now that I have the
array, I can render out a table to list all the companies.companies
1 2 3 4 5 6 7 8 9 10 |
<table> <tr><th>Name</th></tr> <tr *ngFor="let company of companies;"> <td>{{company.companyName}}</td> <td> <a href="#" (click)="delete(company.id)">Delete</a> </div> </td> </tr> </table> |
Most of this is HTML that you should have no trouble reading.
The first thing that isn’t normal HTML is the
attribute with a loop specified: *ngFor
. I think of this as let company of companies
in C# terms. Since the foreach(var company in companies)
is on the <tr> element, that element (and its children) will get repeated once for each company in the array. So, if there are 3 companies, there will be three <tr> rows.ngFor
The next thing out of the ordinary is the
. If you’ve used Mustache or other client-side templates before, this should seem familiar. It’s just interpolating the value of the {{company.companyName}}
field into the HTML. So if the first companyName
has a value of “Couchbase”, then the output will be <td>Couchbase</td>.company.companyName
Finally, I’ve created a “delete” link in each row. What’s out of the ordinary there is the
attribute. This tells Angular to run some TypeScript when the delete link is clicked. In this case, that’s the (click)
method in the TS codebehind. It’s passing one parameter to that method.delete
With the delete method, the code-behind would look like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
import { Component } from '@angular/core'; import { ICompany } from '../../entityInterfaces.ts'; @Component({ selector: 'companies', templateUrl: './app/components/companies/companies.html' }) export class CompaniesComponent { public companies : Array; public constructor() { this.loadCompanies(); } public delete(id: string) { console.log("Deleting Company: " + id) this.deleteCompany(id); // delete from the companies array for(let i=0; i < this.companies.length; i++) { if(this.companies[i].id == id) { this.companies.splice(i, 1); break; } } } } |
Notice that the
method has a parameter, and since this is TypeScript, it’s a typed parameter.delete
There are three things I’m doing in that delete method:
- Writing a message to console (for debugging/illustration)
- Calling a method that will send a POST or DELETE request to an HTTP endpoint (I’ve omitted that method since the details aren’t important now. I’ve also omitted any use of Promise/callback which would be necessary in an asynchronous situation like this).
- I’m removing the company from the companies field (looping through and splicing out the company with the matching id). Alternatively, I could call loadCompanies and refresh the whole list again, and that would mean another trip to the database.
Step 3 contains some Angular2 magic you should know about: when the
field is changed, Angular2 will notice and automatically update the rendered HTML by running the companies
loop again.*ngFor
Other Stuff
Some other things I’ve been doing that I may blog about later:
- Forms in Angular2: these would allow me to create/edit companies in the above example.
- JavaScript libraries/plugins: for the
method, it would be nice to have a confirmation dialog. I’m using bootstrap, and so it would be nice if I could bring in bootbox to use for confirmation dialogs.delete
- Promises: these are imporant when working asynchronously (like when making HTTP requests to API endpoints)
Conclusion
I remain a skeptic about the long term benefits of these JS frameworks and TypeScript itself (ask me about it on Twitter sometime), but I am taking steps to learn the tools. If after all of this, I’m still skeptical, at least I won’t be an ignorant skeptic.
Some resources to continue exploring TypeScript and Angular2:
- TypeScript
- Angular
- Angular2 sample application for Visual Studio