5/25/16

Routes In Angular2 (Part 2)

In previous post we talked about routes in angular2. We saw some basic example of app using routes. But what about nested routes?

Nested Routes

Lets say for example that we need in our application to have a login page which has no menus on it. After passing authentication user should be redirected to protected pages which have the same menus on each of them:

Step 1

Transfer application to use nested routes is very easy.
First you need to create the middle ware route which will host its own routes directive on it. Lets call it layout.
On this middle ware view we will locate the menu.

import {Component} from 'angular2/core'
import {RouteConfig, Router, Route,  ROUTER_DIRECTIVES} from 'angular2/router';
...
@Component({
  selector: 'layout',
 template: `
    <h2>Hello {{name}}</h2>
    <!-- menu is located here now -->
    <a [routerLink]="['Layout']">Dashboard</a> | 
    <a [routerLink]="['Reports']">Reports</a> |
    <a [routerLink]="['Login']">Login</a>
    <hr>
   <!-- router directive -->
   <router-outlet></router-outlet>, 
 directives: [ROUTER_DIRECTIVES]
})

  
@RouteConfig([
   new Route({path: '/', name: 'Dashboard', component: Dashboard, useAsDefault:true}),
   new Route({path: '/reports', name: 'Reports', component: Reports})
])
export class Layout {
  constructor(){
    this.name = 'Angular2 Nested Routes';
  }
}

Step 2

Next thing lets create the login page which will located at the base root route "/login".

import {Component} from 'angular2/core'

@Component({
  selector: 'login',
 template: `
   <div>
     <h1>Please Log In</h1>
     <div style="text-align:center">
           username:<input> 
     </div>
     <div style="text-align:center">
           password:<input> 
     </div>
     <div style="text-align:center">
      <button (click)="login()">login</button>
    </div>
   </div>  `
})

export class Login {
  constructor(public router: Router){}
  login(){
    this.router.navigate(['Layout']);
  }
}


Also lets create the Dashboard page which will located at the inner route "layout/dashboard".

Step 3

Last thing we should modify the root "app" component so it will support nested routes:

import {Component} from 'angular2/core'
import {RouteConfig, Router, Route,  ROUTER_DIRECTIVES} from 'angular2/router';
import {Layout} from './layout';
import {Login} from './login';


@Component({
  selector: 'my-app',
  template: `
      <router-outlet></router-outlet>
  `,
  directives: [ROUTER_DIRECTIVES]
})
@RouteConfig([
   new Route({path: '/layout/...', name: 'Layout', component: Layout}),
   new Route({path: '/login', name: 'Login', component: Login}),
   {
    path: '/**',
    redirectTo: ['Layout']
  }
])
export class App {
}

Here is running code: Hope you have fun reading...

5/11/16

Routes In Angular2 (Part 1)

What are Routes?

Routes are way to access various parts of website using friendly urls. For example if you have a motorcycle store - it will be very convenient if you can navigate to details of page of awesome suzuki GSX1000 using url like:
mybikestore.com/suzuki/GSX1000

(instead of using things like:
mybikestore.com?product=%20%dfgg;ereGSX1000%dfg
which you have no chance to remember)
This way the url pretty clear for users and makes much more sense for developers too.
cannot stop myself from putting here picture of GSX1000 2016

Routes in Angular2

Since when talking about angularjs2 we talking about single page application architecture there all the work done by javascript. The routes in angular (both 1. and 2) is the way to load different views (like different pages) of the website. The changes in url triggering javascript event and javascript responds by loading corresponding views, pretty cool isnt it?

Server

Speaking about single page application - the idea of single page app is that only one page should be served from the server - so it need to be specially configured.
Here is configuration of nodejs express server which makes it to serve only index page no matter of what route was chosen.

var express = require('express');
var app = express();
app.use(express.static(__dirname));

app.get('/*', function(req, res){
    res.sendFile(__dirname + '/index.html');
});
app.listen(process.env.PORT || 3000, function () {
  console.log('Example app listening on port 3000!');
});



Routes in angular2

To implement routes in angular2 'angular2/router' module must be included


import {ROUTER_PROVIDERS, APP_BASE_HREF} from 'angular2/router';

Also, in the code of main component must present route definitions part - a code which defines the routes and their urls:

@Routes([
  {
    path: '/',
    component: DashboardComponent
  },
  {
    path: '/reports',
    component: ReportsComponent
  }
])

Notice that in this example we have two views: "Dashboard" and "Reports"

View

Like in angular1 - if you want to load routed views in your application you must use the ROUTER DIRECTIVE in the view of the component


import {Component} from 'angular2/core';
import {ROUTER_DIRECTIVES, Router, Route, RouteConfig} from 'angular2/router';
...

@Component({
  selector: 'app',
  template: `
    ...
    <router-outlet></router-outlet>
  `,
  directives: [ROUTER_DIRECTIVES]
})

Here is running code: Hope you have fun reading...

4/14/16

Events In Angular2

Like in angular1 you can use events in angular2. What events good for? To make distant components to notify one to another.

How to send event

Everybody knows that for sending event you need to create some kind of channel. This channel will be used to publish(emit) event and to subscribe to event for getting notified . Angular2 has its own EventEmitter class just for this scenario


import {Injectable, EventEmitter} from 'angular2/core';
@Injectable()
export class EmitterService {
  private static _emitters: { [channel: string]: EventEmitter } = {};
  static get(channel: string): EventEmitter {
    if (!this._emitters[channel]) 
      this._emitters[channel] = new EventEmitter();
    return this._emitters[channel];
  }
}

This service sets some channel (if no channel exists) and stores it in the private member

Challenge

In this post i want to demonstrate usage of events by bulding a refresh chart button, of the panel on which a flot component from older posts is located.
pressing on this button should refresh the data of the chart in the child flot component.

Click Event

Sending and catching click event is pretty straightforward:
Sending


<a href="#" panel-refresh="" (click)="chartRefresh();false">
    <em class="fa fa-refresh"></em>
</a>

Catching

  ...
  chartRefresh(){
   this.getEntries();
  }
  ...

The problem is to send custom event from parent component panel
to its child conmponent flot that will cause chart to redraw itself.
This event must be fired after data loaded through ajax request.


  ...
    this.f.getFlotEntries()
      .subscribe(entries => {
        //here event is emitted
        this.e.emit('Broadcast');
      },
  ...

Full Code Of Panel Component


import {Component} from 'angular2/core'
import {FlotCmp} from './flot';
import {FlotService} from './FlotService';
import {EmitterService} from './EmitterService';
import {Observable}     from 'rxjs/Observable';
import {HTTP_PROVIDERS}    from 'angular2/http';
import {Http, Response} from 'angular2/http';
@Component({
  selector: 'panel',
  providers: [],
  template: `
 <div class="panel panel-default">
    <h2 class="panel-heading">
    <div class="pull-right">
    <a href="#" panel-refresh="" (click)="chartRefresh();false"><em class="fa fa-refresh"></em></a>
    </div>
    <div>panel heading</div>
    </h2>
    <flot class="panel-body" height="250px" width="100%"></flot>
 </div>
  `,
  directives: [FlotCmp], 
  providers: [
    FlotService,
    EmitterService,
    HTTP_PROVIDERS
  ] 
})
export class Panel {
  
  constructor(private f:FlotService,private e:EmitterService) {
    
    this.e = EmitterService.get("channel_1"); 
    this.getEntries();
  }
  getEntries(){
    this.f.getFlotEntries()
      .subscribe(entries => {
        //here event is emitted
        this.e.emit('Broadcast');
      },
      error =>  {
        this.errorMessage = error;
         console.log(error);
      });    
    
  }
  chartRefresh(){
   this.getEntries();
  }
}

Handling event

Child component flot responding to custom event from its parent.


   ...
   this.emitter.subscribe(msg => {      
       $.plot( plotArea, this.dataset, this.options);
   });
   ...

Getting started with docker

It is very simple to get started usig docker. All you need to do-is download the docker desktop for your system Once you get docker syste...