7/29/16

React - Building Search App (Part 1)

Get Started

So, if you asking yourself how is it feels to program react - you may easily create your first react app withing seconds:

1. go to plunker
2. click on the down arrow in the green button on the top with caption "new"
3. select "react" or "react with addons" and yes, you have created your first react app!
Yes, it currently only says "Hellow World", but from this second no man can say you never programmed react...

Components are basic part of react

When building React app you must start from building components. So lets create our first component - searchPage


     var SearchPage = React.createClass({
      render: function() {
        return (
          <div>here will come search results...</div>
        );
      }
    });
    
    ReactDOM.render(
        <SearchPage />,
        document.getElementById('example')
      );
running code
Thats it - was not too complicate, right? If you want to get more of this stuff - follow the next part

7/21/16

Building A Short-Description Pipe Angular 2

Pipe is same thing that filter in angluar1. Lets take a look on code that checks if field has too much characters and if it has - replaces the extra characters with ... :


import { Pipe } from '@angular/core';

@Pipe({
  name: 'short_description'
})
export class ShortDescriptionPipe {
  transform(value) {
    let transformedValue;
    if (value && value.length > 100) {
      transformedValue = `${value.substring(0, 100)}...`;
    } else {
      transformedValue = value;
    }

    return transformedValue;
  }


Now if we have some field contain more than 100 characters it will display only first 100 characters

    <div>
      <h2>Hello {{name | short_description }}</h2>      
    </div>

Extending The Pipe To Get "Maximum Chars" Param

In previous code the characters length is statically restricted to 100 chars. But what if we wish to dynamicaaly pass the maximum chars number?


    <div>
      <h2>Hello {{name | short_description : 4}}</h2>      
    </div>
As in angular1 the pipe params prefixed with ::

import { Pipe } from '@angular/core';

@Pipe({
  name: 'short_description'
})
export class ShortDescriptionPipe {
  transform(value, args?) {//args contains param
    if(!args ){
      args= 100;
    }
    let transformedValue;
    if (value && value.length > args) {
      transformedValue = `${value.substring(0, args)}...`;
    } else {
      transformedValue = value;
    }

    return transformedValue;
  }


7/11/16

3 Different Ways To Use ngFor

Introduction

Like ng-repeat directive of angular 1. there is ngFor directive in angular2. it uses for display lists of items.
For example sake - lets take situation we need to display table of site users.
In old angular1 the template should look like this:
angular1 template


    <div>
      <h2>{{name}}</h2>
      <div  ng-if="userList.length===0">No Users Yet</div>
      <table ng-if="userList.length" >
        <tr><th>First Name</th><th>Last Name</th></tr>
        <!-- Look here -->
        <tr ng-repeat="user in userList">
         <td>
           {{user.firstName}}
         </td>
         <td>
           {{user.lastName}}
         </td>         
        </tr>
      </table>
    </div>

And here is controller & service code:
angular1 code

   //service 
   app.factory('usersSrv', function($http, $q) {
     function get(){
       var defer = $q.defer();
       $http.get('./users.json').success(function(data){
         defer.resolve(data)
       });
       return defer.promise;
     }
  
     var service = { 
        getUsers: get
     }

     return service;
   });
    //controller:
   $scope.userList = [];
   usersSrv.getUsers().then(function(users){
    $scope.userList = users; 
   })

Code: plunkr


The same scenario could be written in angular2 like this
template of app.component.ts

      <table *ngIf="userList.length">
        <tr>
            <th>First Name</th>
            <th>Last Name</th>
        </tr>
        <!-- Look here -->
        <tr *ngFor="let user of userList">
         <td>
           {{user.firstName}}
         </td>
         <td>
           {{user.lastName}}
         </td>         
        </tr>
      </table>

If there are some users in our db - they will be shown in table.
Currently the data taken from static array:

export class App {
  public userList:Array=[];
  constructor(userService:UserService) {
    this.name = 'Users Table:'
    this.userList =  [{firstName:'Vasia', lastName:'kozlov'}]
  }
}

we can see users table and everything is fine.

Code: plunk

Promise

The things starting to be more complicate when users collection is loaded from http request. It is complicate because users data now is asyncronous.
So, the first way to handle this thing is to use good old Prmoise known to us well from angular1.
Unlike angular1 we need to import toPromise operator of rxjs library.
users.servise.ts:


import { Injectable }    from '@angular/core';
import { Headers, Http } from '@angular/http';
import 'rxjs/add/operator/toPromise';//import of "topromise" method from rxjs lib

@Injectable()
export class UserService {
  private url:string = './users.json';
  constructor(private http: Http) {}
  getUsers(): Promise {//method must return promise
    return this.http.get(this.url)
    .toPromise()
    .then(response => response.json());
  }
}

Now in the component code we able to use the "then" method for getting the callback of asyncronous method.
app.component.ts:

import {Component} from '@angular/core';
import {UserService} from './user.servise';
@Component({
  selector: 'my-app',
  providers: [],
  template: `
      ...
      ...
      ...
  `,
  providers: [UserService]
})
export class App {
  public userList:Array=[];
  constructor(userService:UserService) {
    this.name = 'Users Table:'
    userService.getUsers().then(//Here we can use "then"
      users => this.userList=users,
      error => console.log(error)
    );
  }
}

The good side here (for me) is that it very similar to angular1 way.
Code: plunk

Subscribe

The second attitude is to use map method of rxjs library.
users.servise.ts:


import { Injectable }    from '@angular/core';
import { Headers, Http } from '@angular/http';
import 'rxjs/Rx';

@Injectable()
export class UserService {
  private url:string = './users.json';
  constructor(private http: Http) {}
  getUsers() {
    return this.http.get(this.url).map(response => response.json());
  }
}

This map method returns Rx.Observable object, thus in component code we will need to use subscribe for handle the async data:
app.component.ts:

import {Component} from '@angular/core';
import {UserService} from './user.servise';
@Component({
      ...
      ...
      ...
  providers: [UserService]
})

export class App {
  public userList:Array=[];
  constructor(userService:UserService) {
    this.name = 'Users Table:';
    userService.getUsers().subscribe(
      users => this.userList=users,
      error=>console.log(error)
    );
  }
}

I like this way because it looks more shorter (no need to use conversion to promise like in previous way).
Code: plunk

Using Async Pipe

Unlike in angular1 there is a way in angular2 to pass observable collection directly to ngFor directive.
We can do this using angular2 async pipe.
template of app.component.ts


    <div>
      <h2>{{name}}</h2>
      <div  *ngIf="userList.length===0">No Users Yet</div>
      <table >
        <tr><th>First Name</th><th>Last Name</th></tr>
        <!-- Look here -->
        <tr *ngFor="let user of userList | async">
         <td>
           {{user.firstName}}
         </td>
         <td>
           {{user.lastName}}
         </td>         
        </tr>
      </table>
    </div>

Usinp async pipe makes the component code even more shorter: app.component.ts:

import {Component} from '@angular/core';
import {UserService} from './user.servise';
@Component({
      ...
      ...
      ...
  providers: [UserService]
})

export class App {
  public userList:Array=[];
  constructor(userService:UserService) {
    this.name = 'Users Table:';
    //no subscribe needed
    this.userList=userService.getUsers();
  }
}

Little More About Async Pipe

Another cool thing about this pipe is - that it can be used not only in ngFor
For example - if you need to show "No Users Yet" message when no users found in DB, you may use async pipe too:
template of app.component.ts


    <div>
      <h2>{{name}}</h2>
      
      <!-- HERE -->
      <div  *ngIf="(userList | async)?.length===0">No Users Yet</div>
      <table *ngIf="(userList | async)?.length>0">
        <tr><th>First Name</th><th>Last Name</th></tr>
        <tr *ngFor="let user of userList | async">
         <td>
           {{user.firstName}}
         </td>
         <td>
           {{user.lastName}}
         </td>         
        </tr>
      </table>
    </div>


Code: plunk

Hope you have fun reading...

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...