Monday 31 October 2016

Configure routes in the Angular2 applications

In this post we are going to see how to configure the routing in Angular2 applications, in previous versions we are used the ngRoute and UiRouter concepts to configure the Route, it is almost similar to that , but we are using here the Module system to configure the Routes.

import { Routes, RouterModule } from '@angular/router';


const routes: Routes = [
  { path: 'rating', component: webformComponent },
  { path: 'news',component:NewsComponent},
  { path: '', component:webformComponent },
  { path: '**', component:UnknownComponent }
];


export const routedComponents = [AppComponent, webformComponent,
     NewsComponent,PrintComponent,UnknownComponent];


@NgModule({
  imports : [CommonModule,RouterModule.forRoot(routes)],
  declarations:routedComponents,
  exports: [RouterModule,EditorModule,CommonModule],
})

export class AppRoutingModule { }


From the above code you can see that the RouterModule and Routes are used to configure the Routes.

We have to give the path and component which have to load for that url, here you can see the RouterModule.forRoot is used to load the routes , in overall applications we should have only one root route, others are must be child, because it is defines that is already defines and creates, so we dont need to create again and again, Here you can see the path is given as empty that means default routing, another one you can see is '**' that specifies the path whatever may be other than configured is routed to unknown component., Now this is the root component for Router module which is stored in separate file, so we have to configure or add this to main module, so we are configure the RouterModule to be exports , then only it can be import or can be used in another module.


Now we will define another set of routing which is separate from this , in this sample we are configuring and separating the routes based on module.


  import { NgModule } from '@angular/core';
  import { CommonModule} from '@angular/common'
  import { FormsModule } from '@angular/forms';
  import { Routes, RouterModule } from '@angular/router';
  import { EmployeeComponent,StudentComponent } from './employee.component'
  import { EmployeeDetailComponent } from './employee.detail'
  import { EmployeeDetailGuard } from './employeeDetailGuard';
  import { EmployeeResolver } from './employeeDetailResolve'
  import { EmployeeFilterPipe } from './employeePipe'

  const routes: Routes = [ 
    { path: 'employee',component:EmployeeComponent},
    { path: 'employee/:id',component:EmployeeDetailComponent, 
                canActivate:[EmployeeDetailGuard],
                resolve:{ userinfo:EmployeeResolver }},
    { path: 'student',component:StudentComponent},  
  ];

  export const routedComponents = [EmployeeComponent,StudentComponent,
  EmployeeDetailComponent,EmployeeFilterPipe];

  @NgModule({
    imports : [CommonModule,FormsModule, RouterModule.forChild(routes)],
    declarations:routedComponents,
    providers:[EmployeeDetailGuard,EmployeeResolver],
    exports: [RouterModule,FormsModule],
  })

  export class UserRoutingModule { }


Now we have to import both the module system in the main module which loads the application, in the above sample you can see the route is configure as ForChild, this is because we have to configure the routes as Root for only one time,
Finally we are going to import the both the things in Main module, in the above code you can see the CanActivate and Resolve properties in routes , we will discuss about this things in later posts.

import { NgModule } from '@angular/core';
    import { BrowserModule } from '@angular/platform-browser';
    import { FormsModule } from '@angular/forms';
    import { HttpModule } from '@angular/http';
        
    import { FocusedDirective } from './directives/onload.directive';
    import { FocusOnLoadDirective,RgMultilineEllipses } from './directives/onload.directive';
    import { FormComponent } from './Forms/form.component';
    import { BaseRequestOptions, Http, Headers } from '@angular/http';
    import { webformComponent } from './Component/web.component'
    
    import { AppLoadComponent } from './app.load.component'

    
    import { DataService } from './data.service';
    import { AppRoutingModule } from './app.routing.module'
    import { UserRoutingModule } from './user.routing.module';
  
    @NgModule({
        imports: [BrowserModule,HttpModule,UserRoutingModule,AppRoutingModule],
        exports: [],
        declarations: [AppLoadComponent,FormComponent,FocusedDirective,
                 RgMultilineEllipses],
        providers:[DataService],
        bootstrap:[AppLoadComponent]
    })
    export class AppModule { 

    }


In the module you can see that the both the Router module are imported, Main module loads the both the routes because the router module is exported in both modules,Now we will see how to configure the router links and containers


<div>
    <nav class="navbar navbar-fixed-top navbar-inverse">
        <div class="container-fluid">
            <div class="navbar-header">   
                
                <button type="button" class="navbar-toggle collapsed" 
                      data-toggle="collapse" 
                    data-target="#angular-collapse-menu" 
                    aria-expanded="false">
                    <span class="sr-only">Toggle Navigation</span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                                             
                <a class="navbar-brand" href="#">Angular 2</a>
            </div>
            <div class="collapse navbar-collapse" id="angular-collapse-menu">
                <ul class="nav navbar-nav">                    
                        <li>
                            <a [routerLink]="['/employee']">Employees</a>
                        </li>
                        <li>
                            <a [routerLink]="['/student']">Student</a>
                        </li>
                        <li>
                            <a [routerLink]="['/rating']">Rating</a>
                        </li>
                        <li>
                            <a [routerLink]="['/news']">News</a>  
                        </li>
                    </ul>
            </div>
            
        </div>                        
    </nav>    
</div>
<div style="padding-top:65px;">
    <router-outlet></router-outlet>
</div>



that's it everything is configured, [routerLink]="['/news']"  is used to create a router link which will call the path /news and NewsComponent instance is created,  <router-outlet> </router-outlet>  is used to inject the view in the container we will load the applications, Let we see the output.


























From this post you can see how to configure the Routes and RoutesModule for the Angular2 Applications.




Friday 28 October 2016

Load the Template in Angular2 Component with relative Url

In this post we are going to see how to Load the template in Angular2 Component with relative Url. Normally when you see the component if you have the TemplateUrl where we will specify the path  which will starts from the path what we specified in the system.config.js, for Example in below example we can see the for a star rating component we have html which is also in the same directory but it is specified from the root path.





From the above example you can see the output of that configuration.





Star Rating Component is a reusable component, here we have one issue, whenever we are adding this another project we have to configure it in the same path because it is specified from the root, so what we can do is,  we change the path to relative path ,relative to component location.







Now we got one issue, template is not loaded because it is mapped related to the root server path,








Now how we can fix this issue,we have to tell the component to have moduleId, which will help the component to load the template with relative to the component location.





Now see the output:







From this post you can see how to load the template in Angular2 component with relative path.



Monday 24 October 2016

Create a Print Component in Angular2 which will print the user defined HTML element in DOM using Typescript (Print component)

In this post we are going to see how to create a Print component which will print the user defined element in DOM using the Typescript, for this first we have to create a Print component then we have to use that component in another component, later we will get a print button in the screen, then when we click the print button, we can find the print of that particular area in the printer.








Component:


import {    Component,ViewEncapsulation,
            Input,Output,OnChanges,ElementRef,
            EventEmitter } from '@angular/core';

@Component({
    selector:'print-page',
    encapsulation:ViewEncapsulation.None,
    template:`
     <button (click)="printDiv()" 
        class="btn btn-sm btn-primary">Print</button>
     <div id="printpage">
     </div>
    `,
    styles:[`
    @media screen {
        #printpage, #printpage * {
            display:none;
        }
    }
      @media print {
          body *{
              visibility:hidden;
              background: transparent;
            -webkit-print-color-adjust: exact !important; 
          }
          
          #printpage, #printpage *{
              visibility:visible;
               -webkit-print-color-adjust: exact !important; 
                box-shadow: inset 0 0 0 1000px gold;
          }

          #printpage{
            position:absolute;
            left:0;
            top:0;             
          }
      }
    `]

})
export class PrintComponent implements OnChanges{
    
    @Input('section') section:string;
    @Output() sectionChange = new EventEmitter<any>(); 

    constructor(private ele:ElementRef){
        if(this.section===undefined)
            this.section = '';
    }

    ngOnChanges(changes){
        if(changes.section && changes.section.currentValue!==undefined
        && changes.section.currentValue!==''){
           
        }
    }

    afterPrint(){
        console.log("after print");
        this.ele.nativeElement.children[0].innerHTML = '';
        this.sectionChange.emit(''); 
        this.section = '';
        
    }
 

    printDiv() {

        if(this.section && this.section != undefined && this.section!='') {
            var printContents = document.getElementById(this.section).innerHTML;
            var originalContents = document.body.innerHTML;      

        if(window){
            if (navigator.userAgent.toLowerCase().indexOf('chrome') > -1) {
                var popup = window.open('', '_blank', 
                'width=600,height=600,scrollbars=no,menubar=no,toolbar=no,'
                +'location=no,status=no,titlebar=no');
               
                popup.window.focus();
                popup.document.write('<!DOCTYPE html><html><head>  '
        +'<link rel="stylesheet" href="node_modules/bootstrap/dist/css/bootstrap.css" '
        +'media="screen,print">'
        +'<link rel="stylesheet" href="style.css" media="screen,print">'             
        +    '</head><body onload="window.print()"><div class="reward-body">' 
        + printContents + '</div></html>');
                popup.onbeforeunload = function (event) {           
                    popup.close();          
                    return '.\n';
                };
                popup.onabort = function (event) {             
                    popup.document.close();           
                    popup.close();         
                }
            } else {
                var popup = window.open('', '_blank', 'width=800,height=600');
                popup.document.open();
                popup.document.write('<html><head>'+
        +'<link rel="stylesheet" href="node_modules/bootstrap/dist/css/bootstrap.css"'
        +' media="all">'
        +'<link rel="stylesheet" href="style.css" media="all">'                
        +'</head><body onload="window.print()">' + printContents + '</html>');
                popup.document.close();
            }

             popup.document.close();
            }
            return true;
        }
    }

fetchStylesheets(){
     var output:string= '';
     for(var i=0;i<document.styleSheets.length;i++){
       output = output +' <link rel="stylesheet" type="text/css" href="'+    
                window.document.styleSheets[0].href +'" /> ';
     }
     return output;
 }

 fetchscriptSheets(){
     var output:string= '';
     for(var i=0;i<document.scripts.length;i++){
       output = output +' <script type="text/javascript" src="'+    
                window.document.scripts[0].src +'" /> ';
     }
     return output;
 }
   
}




In the above component you may notice one things i am created a two methods fetch the stylesheets , scripts, but i didnt use it, if you want to use in the output to load the scripts in printing then you can added that in the execution .


using the print component in another employee component:, for more detail reference about the employee component 
please refer previous post. for service and model data



import { Component } from '@angular/core';
import { DataService } from './data.service';
import { IUser } from './user'

@Component({
    selector:'employee',
    template:`
    <div style="display:inline-block;width:400px;vertical-align:top">
        <h1>Employee </h1>
        <div>
            <input type="text" #emp />
            <button (click)="addEmployee(emp.value)" 
                class="btn btn-sm btn-primary">Add Emp</button>
            <button (click)="getEmployee()" 
                class="btn btn-sm btn-primary">Get Employees</button>
            <div style="margin-top:20px">
            <ul class="list-group" style="display:-webkit-box;overflow-x:scroll">
                <li class="panel list-group-item-primary" 
                *ngFor="let e of employees" style="list-style:none;">
                <div class="panel panel-default">
                <div class="panel-heading">
                    <h3 class="panel-title">{{e.username}}</h3>
                </div>
                <div class=""panel-body>
                    <div class="text-info" style="padding:5px;">{{e.name}} 
                    <span class="btn btn-sm btn-primary" 
                        (click)="getAlbum(e.id)">Get Album</span></div>
                    <div class="text-primary" style="padding:5px;"> 
                        {{e.address.city}},{{e.address.zipcode}}</div>
                    <div *ngIf="e.albums">
                    <ul class="list-group">
                    <li class="list-group-item" *ngFor="let alb of e.albums">
                        <div class="panel panel-default">
                            <div class="panel-heading">{{alb.title}}</div>
                            <div class=""panel-body>                       
                                <img [src]="alb.thumbnailUrl" />
                            </div>
                        </div>
                    </li>
                    </ul>
                    </div>
                </div>
                </div>
                </li>
            </ul>
            </div>
        </div>
    </div>
    `   
})
export class EmployeeComponent
{
    employees:IUser[];
  
    constructor(private dataservice:DataService){
        
    }

    addEmployee(employeeName)
    {
        this.dataservice.addEmployee(employeeName);
    }

    getEmployee(){
        this.dataservice.getEmployees()
        .subscribe(
            customer=>this.employees=customer,
            error=>console.log("error"+error)
            );
       
    }

    getAlbum(id){
        this.dataservice.getAlbums(id)
        .subscribe(
            albums=>this.employees.find(emp=>emp.id==id).albums = albums
            );
    }
}


When user click on the get album, it will fetch information about the particular user id's album , then click print button 

Output:


















After click the print button , the view of the print screen















From this post you can learn how to create a print component in the angular2 using the Typescript which will print the user defined element in the DOM