Mobile Time Tracker Sep 2016
Angular 2 is out for a few days now (Angular 2). With Angular 2 TypeScript is coming, a compiler with static typing ("Javascript which scales!”). As a java developer, mostly working in the back end, I kind of like compilers and therefore decided to give it a try.
So I did a small time tracker front end, which I can use on my mobile for tracking my time spent in projects.
- Note 1: This might no work perfectly well in browsers other than the newest ones. I did not include any compatibility libraries.
- Note 2: In the example below there is no real back end connected, but an in-memory dummy data store.
As already said I like types:
export class AppModel { loadedDate: Date; times: Array<Time> categories: Array<string> getTotalHours(): number { var result = 0.0; if (this.times != null) for (let time of this.times) { const diff = ... result = result + diff; } return result / 60.0; } } export class Time { id: number; from: string; to: string; }
The concept of modularity looks very promising and might scale well for bigger projects. HTML and javascript, which belong to each other make up a component:
import {Component} from '@angular/core'; import {Router} from '@angular/router'; import {AppModel} from './model'; @Component({ selector: 'categories', template: ` <label>categories:</label> <table> <tr *ngFor="let cat of model.categories"> <td><input type="checkbox" [checked]="isChecked(cat)" (change)="change(cat)" /></td> <td>{{cat}}</td> </tr> </table> <div> <button (click)="set()" class="actionBtn">set</button> <button (click)="cancel()" class="actionBtn">cancel</button> </div> ` }) export class CategoriesComponent { private selectedCats: Array<string> constructor(private model: AppModel, private router: Router) { this.selectedCats = model.getTimeRow().cats.slice(); } isChecked(cat: string): boolean { return this.selectedCats.indexOf(cat) != -1; } change(cat: string): void { this.selectedCats.push(cat); } set(): void { this.model.getTimeRow().cats = this.selectedCats; this.router.navigateByUrl("day"); } cancel(): void { this.router.navigateByUrl("day"); } }In the html template syntax you can see
- (change) which binds an action defined in the class below,
- [checked] which establishes the binding between model and view,
- {{cat}} which prints out some attribute in the model,
- and *ngFor for iterating over the model.
For modularity dependencies have to be defined: The CategoriesComponent does import the AppModel class
import {AppModel} from './model';and the AppModel is also injected into the constructor:
constructor(private model: AppModel, private router: Router) { ...
Setup
The project setup has been surprisingly simple after I started to use the angular cli. The cli can
- create an empty project which is a good starting point,
- serve your source to the browser during development and
- build a production ready set of deployable files, minification included.
Final thoughts
With the angular 2 support in IntelliJ nice code completion as well as navigating is possible. The typescript compiler does catch some errors early while developing. Although IDE and compiler support are not as good as a java developer might be used to, from my perspective the javascript universe is clearly moving in the right direction.
Souces available on GitHub: https://github.com/micgn/ttng2