Showing posts with label angular. Show all posts
Showing posts with label angular. Show all posts

Thursday, November 24, 2016

Angular 2 - Time to jump in! (Firebase)

*** This blog was written with Angular2 RC-3, I will be updating to the latest release shortly.  Thanks! ***

From my previous posts we got the Splat Shot score keeping UI components created with just some basic static text.  This post will concentrate on setting up and storing data in Google's latest Firebase platform.  I stumbled upon Firebase a few years ago before they were acquired by Google. Back then the greatest selling point of Firebase is the ability to 'push' data changes from one client to another.  Let's say someone updates the score of a match, and another person is on the site reviewing the leaderboard, the score change will update the leaderboard automatically without the other using having to refresh.  At Google IO 2016, they announced a new and updated Firebase 'platform' and it is nothing short of awesome!  They still have the ability to push data changes to clients, but now they integrate other Google services like  authentication, manage and communicate with groups of customers they call 'audiences', ad management, analytics and much, much more.  This list of YouTube videos is a really great overview introducing all the capabilities of Firebase.

For the rest of this post, we are going to assume that you have created a Firebase account and started a new project.  In this example, I created a Firebase project called 'splatshot':



As noted in the screen shot above, database rules are not set, meaning anyone can update data.  Since this is just a test application I am not going to get into database rules, but there is a lot of great information on the Firebase site regarding security rules.  In order to use Firebase from our application, we are going to use the new AngularFire2 library.  Follow these instructions (starting at step 2) to install Firebase in the Splat Shot application running the commands from your root application directory.  From the install instructions we will cover the injection and binding with the player list (do not need to do steps 8 - 10).  Once complete, also make sure to stop your current 'ng serve' process (if running) and run a full 'ng build'.  (If you are using Cloud 9, make sure to start your ng serve with a specific livereload port:  ng serve --port 8080 --live-reload-port 8082).

Once we have Firebase setup, lets start by creating an interface for a player.  This follows the pattern from Debroah Kurata's Movie Hunter example.  From the root project directory type the following command, the player/player means place this player interface in the +player directory (ie: ng g interface [directory]/[interfaceName]):

1
ng g interface player/player

The 'g' is shorthand for 'generate'.  You should see a new interface in the src/app/+player directory.  Add the following fields to the code:

1
2
3
4
5
6
export interface Player {
    firstName: string;
    lastName: string;
    email: string;
    phone: string;
}

Now that we have the player fields we want to track, next lets create a player service to interact with Firebase to read and write player information:

1
ng g service player/player



Angular 2 - Time to jump in! (Design)

*** This blog was written with Angular2 RC-3, I will be updating to the latest release shortly.  Thanks! ***

This is a series of posts on learning Angular2, you can review my Intro and Setup posts for more information.  Back to our Racquetball League score keeping application Splat-Shot, let's take a look at what we want the application to do and how it should be designed:

  • Need to keep track of a list of Players with:
    • Name
    • Phone
    • Email
  • Need to create a league which includes:
    • Players
    • Courts
    • Match Date / Time
    • Match Results
  • Need to create a Leader board summarizing match results
From a UI perspective we need:
  • Home screen
  • Menu Bar
    • Players
    • Matches
    • Leader board
  • Player
    • List
    • Edit
  • League
    • List
    • Update match results
  • Leader board - ordered list of players by match results
Other rules:
  • A match consists of 3 games
  • Each game is played to 15 points.
  • The winner of each game gets a match point.  If you win all three games, you get a bonus match point.
Let's start with the easy one first, creating a home screen, tool bar and slide navigation menu.  First we need to import the material design components:

  'core',
  'toolbar',
  'icon',
  'button',
  'sidenav',
  'list',
  'card',
  'input',
  'radio',
  'checkbox'

(follow instructions from setup, also make sure to follow the extra setup steps for MdIcon).  When creating a new application with AngularCLI, it creates a default component with your application name, in our example splat-shot.component.ts.  First, lets create the toolbar and menu bar:

src / splat-shot.component.ts

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
import { Component } from '@angular/core';
import {MdToolbar} from '@angular2-material/toolbar';
import {MdButton} from '@angular2-material/button';
import {MD_SIDENAV_DIRECTIVES} from '@angular2-material/sidenav';
import {MD_LIST_DIRECTIVES} from '@angular2-material/list';
import {MD_CARD_DIRECTIVES} from '@angular2-material/card';
import {MdIcon, MdIconRegistry} from '@angular2-material/icon';

@Component({
  moduleId: module.id,
  selector: 'splat-shot-app',
  templateUrl: 'splat-shot.component.html',
  styleUrls: ['splat-shot.component.css'],
  directives: [
    MD_SIDENAV_DIRECTIVES,
    MD_LIST_DIRECTIVES,
    MdToolbar,
    MdIcon
  ],
  providers: [MdIconRegistry]
})
export class SplatShotAppComponent {
  
  title = 'splat-shot works!';
  
  views: Object[] = [
    {
      name: "Home",
      description: "Latest News in the League.",
      icon: "home"
    },
    {
      name: "Matches",
      description: "Show the upcoming matches.",
      icon: "perm_contact_calendar"
    },
    {
      name: "Players",
      description: "Show List of players.",
      icon: "people"
    }
  ];
  
  
}

In the code sample above, we import the material design components and setup our directives.  This menu bar design was taken from the PuppyLove example where the views is an object array that is then populated in the HTML file using an *ngFor Loop:

src \ splat-shot.component.html


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
<md-sidenav-layout fullscreen>
  <md-sidenav #sidenav>
    <md-nav-list>
      <a md-list-item *ngFor="let view of views">
        <md-icon md-list-icon>{{view.icon}}</md-icon>
        <span md-line>{{view.name}}</span>
        <span md-line class="secondary">{{view.description}}</span>
      </a>
    </md-nav-list>
  </md-sidenav>
  <md-toolbar color="primary">
    <button md-icon-button (click)="sidenav.open()">
      <md-icon>menu</md-icon>
    </button>
    Splat Shot!
  </md-toolbar>
</md-sidenav-layout>

Your application should now look like this:






When you click the menu button, the array of views defined in your component should appear:

In my next post we will look at  creating the components behind the menu items and add routing.



Angular 2 - Time to jump in! (Intro)

*** This blog was written with Angular2 RC-3, I will be updating to the latest release shortly.  Thanks! ***

Introduction


I consider myself a MEAN Stack evangelist, I love being able to use JavaScript / JSON from database to browser, its just easy to ready, easy to debug and overall just brings the fun back to programming (coming from writing Java for 10+ years).  When I first saw Angular 1.X, I thought it was 'black magic', two-way data binding... amazing.  Using Angular Controllers, Services, Directives, along with Mongoose, express-restify-mongoose, and some really cool templates from Wrap Bootstrap (Inspinia), I created some great web applications for my customers.  Naturally I was very excited to hear about 'what's next', thinking "Oh 2.0 is going to be awesome, I'm a $scope / controller fiend" and then at ng-conf 2015, the news broke:  "Angular 2 is throwing out controllers and swapping in components and oh by the way, we partnered with Microsoft and we are writing it in Typescript."  Wait... WHAT????

Fast forward ng-conf 2016 and it appears the initial shock has subsided, Angular 2 RC1 has been released, it appears the clouds are parting and the sun is starting to shine.  I was unable to attend the 2016 ng-conference, but I watched every video on their YouTube channel.  After watching the presentation on Angular CLI, I saw the ability to create a new Angular2 application without having to worry about architecture, gulp or webpack, and I said... "It's time to jump in".  By the way, shout out to the folks over a Scotch.io, I love their write-ups and they have a great summary of ng-conf 2016.

I believe that the best way to learn anything new is to pick a problem and solve it.  I play in a local racquetball league and we keep score on a piece of paper taped to the wall.  I think its time to bring our league's score board into the 2000's with an Angular 2 app (all jokes of old guys with head bands and goggles aside ;) ).

Development Environment

Everyone has their favorite OS and IDE but it just boils down to what is the fanciest text editor that makes me the most productive.  A while back I stumbled on an article about someone using a Chromebook for development and was introduced to Cloud9.  At first I was skeptical, probably just NotePad++ in a browser window, but WOW was I surprised!  Cloud 9 has full command line access, the editor has type-ahead, formatting, easy to search and display files, split views and much more.  I'm just amazed at what can be done through a web browser, and using Cloud9, I don't have to worry about setting up CentOS in a VirtualBox, my IDE travels with me where ever I go, exactly where I left off.

Code Examples

I decided to call my racquetball scoreboard application Splat-Shot in reference to a type of shot in racquetball that creates a distinctive 'splat' sound when it hits the front wall.  So I have the problem I want to solve, but where should I start?  Well let's see what everyone else is doing and then pick the best practices that work best for me.  The speakers at the 2016 ng-conf were great, so I downloaded each of their code examples to my Cloud9 IDE.  Some of them are listed below:

Issue-Zero
Following the same thought process of 'finding a problem and solving it', the Angular team created Issue Zero to help triage the GitHub issues for Angular 2.  This is a really great example, it includes Firebase, Authentication, Observables, Angular Universal... and the list goes on.  While great code, I found trying to learn all of these new technologies at once was a bit overwhelming.

Puppy Love
This is a great example for the use of Angular2's version of Google's Material Design.  With Angular1 I am a huge Bootstrap fan and with the Inspinia template, I had all the UI components I needed to make great looking web applications.  There are other layout / UI component libraries for Angular2 including ng-bootstrap and Telerik Kendo UI, but I'm an Android nut and I love the look and feel of Material Design so I decided to stick with the Material Design team.

Tour of Heros
This is the 'official' Angular2 demo application from the tutorial on the Angular website.

Movie Hunter
My Splat-Shot application demonstration is the culmination of many hours of learning, destroying, and rebuilding the application, again learning what's out there and picking what works best for me.  It was not until I watched the presentation on Angular 2  Forms from Deborah Kurata that I finally said, "Yes, this is what I want my code to look like".  She also has several training videos on Plural Sight.


ng-book 2
I jumped in on the early-bird pricing for this book and was not disappointed.  This is a great summary of Angular2, the code samples are well thought out and easy to read.


Just one more quick reference to the guys at DevChat.tv, Adventures in Angular is a great podcast on everything Angular, they have excellent interviews with Angular team members, 'people in the know' and just all around 'good banter'.

With your IDE set and sample code downloaded, check out my next post getting the Splat-Shot application setup and start writing some code.



Tuesday, June 7, 2016

Angular 2 - Time to jump in! (Routing)

*** This blog was written with Angular2 RC-3, I will be updating to the latest release shortly.  Thanks! ***

In my previous posts we created the toolbar and menu bar for the Splat-Shot application.  Now we need to create the components behind the menu bar and setup some routing.  The first thing to do is create a new component, and the AngularCLI makes this really easy.  Because we also want our components to be routes, use the 'generate route' command.  Make sure you are in the root directory of your project folder /splat-shot and type:

1
ng generate route home

AngularCLI will create the TypeScript component, the HTML / CSS files along with a component test.  By default AngularCLI creates a 'lasy loaded' view designated by the '+home' directory name.  This is listed in the style guide for marking lazy loaded components.  Another interesting point is that you should not explicitly import lazy loaded components in their parent or sibling components, see style guide for more information.  Let's add some basic HTML and CSS:

src / app / +home / home.component.html

1
2
3
4
5
<div class="welcome">
    <h4>Welcome to:</h4>
    <h1>Splat Shot</h1>
    <h4>Racquetball League Scoreboard</h4>
</div>

src / app / +home / home.component.css

1
2
3
.welcome {
    text-align: center;
}

Save both the files and live-reload should kick off and ... nothing happens.  That is because we have to tell our main component to load the home component as the default route.

src / app / splat-shot.component.ts

...
import { Routes, Router, ROUTER_DIRECTIVES, ROUTER_PROVIDERS} from '@angular/router';
...
  providers: [
    ROUTER_PROVIDERS,
    MdIconRegistry
  ]
...
@Routes([
    { path: '/', component: HomeComponent },
    { path: '/home', component: HomeComponent}
])
...
  constructor(private router: Router) {}
 ngOnInit() {
 }
...

Your application should now show the home screen:




I had some help from another really great routing example from Juan Suarez. Now let's add the player list and leaderboard components:


1
2
ng generate route player
ng generate route leaderboard

With the other two routes complete, now lets wire up the menu bar.  The AngularCLI already injected the routes, the only thing we have to update is our menu object array:

src / app / splat-shot.component.ts


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
views: Object[] = [
    {
      name: "Home",
      description: "Latest News in the League.",
      icon: "home",
      route: '/home'
    },
    {
      name: "Matches",
      description: "Show the upcoming matches.",
      icon: "perm_contact_calendar",
      route: '/leaderboard'
    },
    {
      name: "Players",
      description: "Show List of players.",
      icon: "people",
      route: '/player'
    }
  ];
...

Next, we update our html link to include the routerLink and a click operation to close the menu when a user selects the item:

src / app / splat-shot.component.html


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
...
<md-sidenav #sidenav>
    <md-nav-list>
      <a md-list-item *ngFor="let view of views" 
        [routerLink]="[ view.route ]"
        (click)="sidenav.close()">
        <md-icon md-list-icon>{{view.icon}}</md-icon>
        <span md-line>{{view.name}}</span>
        <span md-line class="secondary">{{view.description}}</span>
      </a>
    </md-nav-list>
  </md-sidenav>
...

You should now be able to select a menu item and have it switch between the different components:























In my next post, we will be looking at adding more functionality to each component than just static text.


Friday, June 3, 2016

Angular 2 - Time to jump in! (Setup)

This post describes setting up my Angular2 demonstration application called 'Splat-Shot'.  I will be using the Cloud9 IDE and code from several other examples, see my Intro post for more information.

Setting up Splat-Shot

Once you have your new Cloud9 Desktop started for NodeJS development (preloads NodeJS and NPM), open a command prompt and type the following (Directions from Angular CLI):


1
2
3
4
npm install -g angular-cli
ng new splat-shot
cd splat-shot
ng serve --port 8080 --live-reload-port 8082


If you are walking through this demo outside of Cloud9, you can just type "ng serve", but Cloud9 only has ports 8080-8082 open, so assign live-reload to port 8082 and changes update as soon as you click save.  (Thanks ng cli team for making the ports assignable, you guys are genius!) In the Cloud9 menu bar at the top click "Preview > Preview Running Application" and a new window will appear with a starting message:

To verify that live-reload is working, navigate to the following file and add the code:

src \ app \ splat-shot.component.html


1
<h2>Live Reload Works!</h2>


The preview should reload automatically and display:


Layout and UI Components

Once we have splat-shot running, time to install Material Design, please follow the instructions from the Material Design GitHub Website.  Once you have made the changes from the installation instructions, stop the current ng serve process and restart, (make sure to set the livereload port if in Cloud 9):

ng serve --port 8080 --live-reload-port 8082

To make sure everything is working, open the following file and add make the changes below:

src \ app \ splat-shot.component.ts


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
import { Component } from '@angular/core';
import { MD_CARD_DIRECTIVES } from '@angular2-material/card';
import { MD_BUTTON_DIRECTIVES } from '@angular2-material/button';

@Component({
  moduleId: module.id,
  selector: 'splat-shot-app',
  templateUrl: 'splat-shot.component.html',
  styleUrls: ['splat-shot.component.css'],
  directives: [MD_CARD_DIRECTIVES, MD_BUTTON_DIRECTIVES]
})
export class SplatShotAppComponent {
  title = 'splat-shot works!';
}

src \ app \ splat-shot.component.html


1
2
3
4
5
6
7
8
9
<md-card>
    <md-card-title>{{title}}</md-card-title>
    <md-card-content>
        Racquetball Score Keeping System
    </md-card-content>
    <md-card-actions align="end">
      <button md-raised-button color="accent">Splat!</button>
    </md-card-actions>
</md-card>

You should now have a Material Design card with a button:



Keep in mind we just imported only the Material Design core, cards, and button.  If you want to use any other components from Material Design, you'll have to import them as well.  For example, let's say you want to use a progress circle, first install the component using npm:


npm install --save @angular2-material/progress-circle
 
Update your configuration and html:
 
src \ system-config.ts


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
...

const materialPkgs:string[] = [ 
  'core', 
  'button', 
  'card', 
  'progress-circle'
];

...

src \ app \ splat-shot.component.ts



 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
import { Component } from '@angular/core';
import { MD_CARD_DIRECTIVES } from '@angular2-material/card';
import { MD_BUTTON_DIRECTIVES } from '@angular2-material/button';
import { MdProgressCircle } from '@angular2-material/progress-circle';

@Component({
  moduleId: module.id,
  selector: 'splat-shot-app',
  templateUrl: 'splat-shot.component.html',
  styleUrls: ['splat-shot.component.css'],
  directives: [MD_CARD_DIRECTIVES, MD_BUTTON_DIRECTIVES, MdProgressCircle]
})
export class SplatShotAppComponent {
  title = 'splat-shot works!';
}


src \ app \ splat-shot.component.html


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<md-card>
    <md-card-title>{{title}}</md-card-title>
    <md-card-content>
        Racquetball Score Keeping System
    </md-card-content>
    <md-card-actions align="end">
      <md-progress-circle mode="indeterminate"></md-progress-circle>
      <button md-raised-button color="accent">Splat!</button>
    </md-card-actions>
</md-card>

You should now have a progress circle spinning next to your button:













NOTE: This process is important, since TypeScript needs to be compiled to JavaScript, you need to tell the AngularCLI the new packages to build and include in your index.html.

Now that we have the 'shell' of the Splat-Shot application up and running with AngularCLI and some Material Design components installed, time to take a break and design the components of the application and their functions.  Check out my next post on design.