After seeing the latest NG-Conf, I thought it was the right time to start learning Angular2. After a long way, Angular2 was finally out of beta. It was no longer an obscure framework where every new feature had the potential to make you rewrite your app.
It's stable, fast and the documentation is packed with really good information and tutorials.

Not only that, TypeScript seemed to be the first option among the Angular team to create new apps. TypeScript is a typed superset of JavaScript that compiles to plain JavaScript. That means that you can use features of ES2015 (former ES6) or newer, and compile it to an older edition of EcmaScript, so it can run on older versions of browsers.

Time to learn TypeScript too.

The purpose of the blog post is to create a very simple todo Angular2 app using TypeScript and Firebase using the AngularFire2 library.


Where to start

I've been an Angular 1.x developer for 2 years, and you may think that is a huge advantage compared to someone who never used this framework before.

It is not.

There are some key features that remain like directives, services, dependency injection, but Angular2 is so different from Angular1 that you can jump right into it.

Editor

The first thing you should do is to setup your environment, and choosing the right editor is key. My editor of choice until today is Sublime Text. Super light, tons of configurations, snippets and an awesome package manager.
Although, to start with TypeScript my choice relied on Visual Studio Code. Being TypeScript developed and maintained by Microsoft, using a Microsoft tool might be the best solution since, in theory, it should be the first to be updated to support TypeScript's latest changes.

If you are used to a unix-based OS like me, installing Visual Studio Code might feel a little bit awkward, but I must say that I'm very pleased with it. And there's also ready-made snippets from John Papa.

Create project

After having your favorite editor running and configured, let's create our first Angular2 app. And it's as easy as installing the Angular CLI (you'll need NodeJS)

$ npm install -g angular-cli

and run the following command on the terminal:

$ ng new ng2todo

After this, an Angular2 app scaffold with the name "ng2todo" has been created and you can run it by entering the folder of the app and run a local webserver.

$ cd ng2todo
$ ng serve

Go to http://localhost:4200 and check your first Angular2 app.

Your first Angular2 app

Done! Easy right? :)

Ok, let's see if we can learn some real stuff and make our first change on our app. Go to the app component (src/app/ng2todo.component.ts) and change the title to "ng2todo list".

Your first Angular2 app

Not bad, but next I'll show you how to create a component from scratch and add some more functionality to our app.

Folder structure

Take a look on the app folder structure.

Folder structure

I'm not going into detail about the purpose of each folder, but check this video if you want to know more about it.

Inside the src directory is where you app is, and inside the app directory is where your app component (ng2todo) lives. Inside this directory there's another folder called shared, where you can create all your components, services, etc., but personally I prefer to create them inside the app directory, so I'll just remove it. Again, this is just a personal thing, you can keep the shared folder if you prefer.

Todos component

Let's create our first component, and instead of doing all by hand we'll use the power of Angular CLI.

$ ng generate component todos

And that's it! It automatically creates a folder with the component, template, styles, injects dependencies and the spec file for tests! How awesome is that?!

Inside the template (todos.component.html) create an unordered list, and using the NgFor directive iterate over the list of todos and create a list item for each of them.

<ul>
  <li *ngFor="let todo of todos">
    <span>{{todo}}</span>
  </li>
</ul>

Inside the component, create the todos list, of type any, and inside the ngOnInit function let's populate the list using some pseudocode.

todos: any[];

constructor() {}

ngOnInit() {
  this.todos = ['Learn Angular2',
                'Check AngularFire2',
                'Fav this article'];
}

Now let's add the created element app-todos to the app template (src/app/ng2todo.component.html), to list the array

<h1>
  {{title}}
</h1>
<app-todos></app-todos>

But the app component still doesn't know what app-todos is, so we need to import the todos component. So, on the app component (src/app/ng2todo.component.ts) let's add the following line on top

import { TodosComponent } from './todos/todos.component';

Adding new todos

Before jumping into AngularFire let's add a functionality to add new items to the list.

On the todos component add an input field with the NgModel directive. This directive is what will give us the two-way data binding.
We'll also be using the keypress.enter event handler to add the inserted value to the list after hitting the Enter key.

<h3>Add new todo:</h3>
<input type="text" [(ngModel)]="newTodo" (keydown.enter)="add()" />

On the component create the add() function

add() {
  this.todos.push(this.newTodo);
  this.newTodo = '';
}

Don't forget to declare and initialize the newTodo property right before the constructor.

newTodo: string = '';

Check the app on http://localhost:4200 and give it a try. On a perfect blog post we should've created the tests before making any changes on the code, but I'll leave it for another article.

New todo working

Persist data on Firebase

Right now the list of the app in only in memory, if you refresh the webpage you'll lose all your changes. In this article I'll show you how to use Firebase to save your data using AngularFire2, a library that integrates Firebase's realtime observers and authentication with Angular2.
Firebase is a back-end as a service that offers you a NoSQL database, an authentication service, analytics and an hosting service, all-in-one.

Install and inject

First, install AngularFire2 and Firebase (v2) as app dependencies.

$ npm install angularfire2 firebase@2.x --save

In order to get Firebase autocomplete you might need to install its typings:

$ typings dt~firebase --global --save

Then we need to tell Angular that we want to use the Firebase providers and services, so we'll bootstrap it on the main.ts file. Here we'll also set the URL of our Firebase app, alongside with the authentication provider and method. Don't mind the URL on defaultFirebase function for now, you'll have to change that but I'll address that further in this article.

And, as usual, we also need to import the modules at the top.

import { FIREBASE_PROVIDERS, defaultFirebase, firebaseAuthConfig, AuthProviders, AuthMethods } from 'angularfire2';

...

bootstrap(Ng2todoAppComponent, [
  FIREBASE_PROVIDERS,
  defaultFirebase('https://ng2tododb.firebaseio.com/'),
  firebaseAuthConfig({
    provider: AuthProviders.Anonymous,
    method: AuthMethods.Anonymous
  })
]);

Angular CLI

If you check you app now you'll get some errors on the browser's console, regarding some files that couldn't be found (angularfire2). That's because Angular CLI needs some extra configuration in order to retrieve the files you need.

Open the file angular-cli-build.json file (you can find it on the root directory of your app) and add the missing lines to get the firebase and angularfire2 files.

module.exports = function(defaults) {
  return new Angular2App(defaults, {
    vendorNpmFiles: [
      'systemjs/dist/system-polyfills.js',
      ...
      'firebase/lib/*.js',
      'angularfire2/**/*.+(js|js.map)'
    ]
  });
};

What this does is to get all the files mentioned and add them to the "dist/vendor" directory.

Now we also need to map the files on the CLI system config packages inside the system-config.ts file. Change only where it says "User Configuration".

/** Map relative paths to URLs. */
const map: any = {
  'firebase': 'vendor/firebase/lib/firebase-web.js',
  'angularfire2': 'vendor/angularfire2'
};

/** User packages configuration. */
const packages: any = {
  'firebase': {
    format: 'cjs'
  },
  'angularfire2': {
    format: 'cjs',
    defaultExtension: 'js',
    main: 'angularfire2.js'
  }
};

Create your Firebase account

By the time I wrote this article, Firebase v3 has already been released, but AngularFire2 only worked with Firebase v2. That means that you need to create an account using the legacy console. I believe that AngularFire2 will soon be updated to work with Firebase v3, but for now this is the only way to make it work.

Inside your account create a new app. In my case I gave it the name "ng2tododb", but you can name it whatever you want. Don't forget to change the your Firebase app URL on the bootstraping method (inside main.ts).

Authentication

You can use your Google, Facebook, Twitter or Github account as well, or register users using email and password. But in order o make this simpler we'll allow anonymous authentication to make changes inside our Firebase app.

On the Firebase console, click Manage App to enter the dashboard of the app you just created. Head to "Login & Auth" option on your left, and inside the "Anonymous" tab, check the option to Enable Anonymous User Authentication.

Now on the app component, import Firebase authentication module from AngularFire2,

import { FirebaseAuth } from 'angularfire2';

and perform the login inside the app component constructor.

export class Ng2todoAppComponent {
  title = 'ng2todo list';

  constructor (private _auth: FirebaseAuth) {
    this._auth.login();
  }
}

Read data from Firebase

Instead of having our list of todo items inside an array in memory, let's link it to Firebase.

On our todo component we're going to need AngularFire,

import { AngularFire } from 'angularfire2';

inject it into the component's constructor,

constructor(private af: AngularFire) {}

and then set our list of todos as follows inside the ngOnInit function:

this.todos = this.af.database.list('/');

If you have your editor properly configured, you might see some red squiggles on this particular line.

Something is wrong here...

This happens because of the power of TypeScript that sees that the type of data returned by the list function is different from the current type of data of the variable todos (which is an array of type any).

Right now, the list of todos is an array that lives in memory, and what we want is to take advantage of Firebase and setup a 3-way data binding (between the DOM, the component and the database), so we need to change the todos variable to an array that changes over time (observable). In this case our todos list is going to be of type FirebaseListObservable.

So at the top, add it to the modules imported from angularfire2,

import { AngularFire, FirebaseListObservable } from 'angularfire2';

and change the type of the todos variable.

todos: FirebaseListObservable<any[]>;

There's still one more change that needs to be done. If you go to the template, we're using an NgFor directive that iterates over an array that lives in memory instead of over time. So we need to pipe the directive to an asyncronous operation.

<li *ngFor="let todo of todos | async">
  <span>{{todo.$value}}</span>
</li>

The Angular AsyncPipe is an interesting example of an impure pipe. The AsyncPipe accepts a Promise or Observable as input and subscribes to the input automatically, eventually returning the emitted value(s).

Angular2 docs

Another change that needs to be made is instead of binding to "todo" inside the span element, bind it to "todo.$value". That is a property of Firebase that returns the value of the object.

You can now open two windows side-by-side and see it in action!

Angular2 + AngularFire2 + TypeScript in action!

Add to firebase

As you can see we've made no change to add a new item to Firebase, the function add() remained the same. It's a simple push.

Delete

Let's change our app so we can delete from an entry from Firebase. On our template add an "x" in front of every entry and bind the click event to call a function called delete that will have the todo as an argument.

<span>{{todo.$value}}</span> <span (click)="delete(todo)">[x]</span>

Now on our component we need to create the delete function.

delete(todo) {
  this.todos.remove(todo);
}

Removing an item

Wrap-up

TypeScript and Angular2 evolved a lot in the previous year, they have been hands together in this journey and it really seems that they have everything on their side to path the future of web app development.
It's still to soon to say but from what we can see so far, its really promissing.

If you have any questions you can reach me on Twitter or Github, I'll make sure to not leave you without an answer.

Also, this app is available on my Github account so feel free to fork or download it.

If you like it and want to see more of this type of articles and learn more about Angular2, show some love by recommending and sharing.

Cheers!