Wednesday 11 April 2018

Angular - netninja - Angular 2 Basics

Angular -youtube-Angualr 2 NetNinja
==================================
Video:1 => what Ng2 ?
-------
js framework for dynamic app. compoent based archi tech not typical MVC based.
core feature
compoent, module, directive, service
simple directory app
routing,service, firebase

Video:2 =>the angular CLI
---------
CLI help create new project (core files) upto deployment level Environment
for this need NPM
$ng new ninja-directory

Video:3 => Typescript Intro
-----------
super set of JS. very similar to Js addianaly classes, types, import, export
in TS - > datatype not reassiable. basic types are -> string, number, boolean, any,array

Video:4 => core files overview
-----------
app/src
config
node_module.....

Video:5 => Angular2 components
-----------
App componet
NAv bar compoent
Blog compoent -> sidebar component and Ariticle component

Video:6 => Templates and CSS
----------

 templateUrl: './app.component.html',
 styleUrls: ['./app.component.css']
if Url not used inside the component itself the dom and Css means need to provide - template and style
style.css is global style sheet. the properties are applciable across the application

Video:7 => creating components
----------
ng g c home

Video:8 => Nested component
-------
angualr 2 - if you need to import the componet means, create index.ts file insde the component. then export the componet
now in angular cli and angualr 4 not required

Video:9 => Ng-content
-----------
app.template.html
<app-home>hello content</app-home>
home.tempalte.html
<p>
  home works!
</p>
<ng-content></ng-content>
o/p with 
home works!
hello content ====> inside the directive data can't show by default.
So, need to provide in sub compnent with <ng-content> direvtive

Video:10 => Data Binding
----------
binding b/w the template and componet

{{ data binding }} string interpolcation
[require]='expression Property binding
(click)="show()" event binding
<input [(ngModel)] ="twoData" two way data binding

Video:11 => property binding
-----------
<input value ="net Ninja"> normal way
<input [value]="net Ninja"> Angular way of property binding

Video:12 =>     Event Binding
-----------

<buton (click)="alrt()">

Video:13 => two way data binding
----------
template to compoent and compoent to template

Video:14 => Input() decorator -> property binding
----------
<app-home [homevalue]="data" >service

Video:15 => Output() event emitter
-----------

Video:16 => Routing
-----------
/
/home
/directory

Video:17 => adding Link to applcation
------
<a rotuerLink="home" > home</a>
const appRoutes : routes [
{path:'home', component: HomeComponent}
]

Video:18 => route params
-----------
import ActivateRoute and make the

{path:'home/:ninja', component: HomeComponent

Video:19 => Directives
-----------
strutural , attribute

Video:20 => *ngFor
--------

Video:21 => pipes
-----------
upper case, date

Video:22 => custom Pipe
---------

 

Tuesday 10 April 2018

Angular 5- POC- techsith Topics with ng4

Angular-youtube-techsith
===================
Source code https://github.com/gnganpath/learningAngular4techsith
topics : Routing, ChildRouting based on url
Serivces, asObservables, BehaviorSubject


Angular 4 Tutorial series of beginners
=======================================
Video:1 -> setup using CLI
----------
node -v -> v6.11.11
npm install -g @angular/cli
to verify angular install
type ng or ng help
crate project with $ng new learningagular4
package.json
------------
All dev and dependecies are mentioned.
dev: agulare cli, karma, zone,
dependecies: angular core, common, http, rxjs
tsconfig.json
-----------
configuration file for compiler option, libra, target:es5

ng serve --open
change the default code and run
ng test will open in localhost:9876 -- some other port and provide the details
before commit your code do the difference
$git diff
$git status
$git add .
$git commit -m "first commit"
$git push -u remote branch

video:2 ->intro to Typescript
--------
typescript is created by microsoft.
Angular1 is MVC based. But want to crate in component archi based.
So, JS don't have component sbased archi. So typescipt will ES6 to transpile ot ES5.

http://www.typescriptlang.org/play/
Ts - data type
let x = 'hi;
x=2;  Type error string not assignable to number error.
But in JS
var x = 'hi';
x = 2; reassignable. not give error in string and number.
So, to solve  this issue,
let x;
x='hi'; then x =2. not error.

But TS standard is => let x:number =2;
Data Types in TS are => string, numberm, boolean, any; [array, null, undefined, void, enum]
public, private, protected access modifier

class car{
public maxSpeed:numner;
private color:string;
protected price:number;
}
class Toyota extends car{
    constructor(maxspeed, color,price ){
    this.maxspeed = maxspeed;  
    this.color = color;  // error. private var we can accesswith getter and setter method.
    this.price = price;
    }
}
public and protected variable are access thorugh subclass not private variable.

Video:3 -> components using cli
----------
component in angular is heart of app.
$ng new learningagular4 from video:1
$ng g c main-container
compontnent.ts
names = ['kt','sa', 'hcl','trz']
maincontainer.html
    <app-outer [outername]="names"></app-outer>
template.html
    {{names }} == > kt,sa,hcl,trz -->even names is arrya while to do interpolation its will be string
$ng g c outer
outer.component.ts
 @Input() outername;
outer.template.html
 <div>{{ outername}}</div>
$ng g inner
inner.component.ts
import { Component, OnInit,Input ,Output,EventEmitter} from '@angular/core';
@Input() innername;
@Output() eventFromInner = new EventEmitter<string>();
sendtoOuter(){
    console.log('emit')
    this.eventFromInner.emit(this.innername);
}
inner.html
<div class="inner">
  inner compoent
  <span class="name">name: {{innername}} </span>
  <button (click)="sendtoOuter()">send to outer</button></div>
 
modify outer

outer.component.ts
 name = '';
 @Input() outername;
  eventFromInner(passed:string){
    this.name = passed;
  }
outer.template.html
 selected : {{name }}
  <div>array names: => {{ outername}}</div>
  <app-inner *ngFor="let name of outername" [innername]="name" (eventFromInner)="eventFromInner($event)"></app-inner>

Conculstion: pass data from inner to outer and alos pass to main-conintainer
child to parent also grandparent

Video:5 angular4/5 HTTP GET/POST requests
----------
import the HttpClientModule in app.module.ts
next need to create server api file.
Same like myjson API, through github we can create and maintain the file like live API

https://github.com/techsithgit/json-faker-directory/profiles/name?=john

using httpInterceptorModule we can do the post opearaiton.

Video:6 => Routing
--------

Home page, about page, user page... inside user -user details page also
If not valid routing page also goto home page

const appRoutes : Routes =[
 
  { path:'home', component:HomeComponent },
  { path:'about', component:AboutComponent },
  { path:'user', children:
    [
      { path: 'list', component:UserlistComponent,
        children: [
          {path: 'detail/:name', component:UserComponent}
        ]
      }
    ]
  },
  { path:'', redirectTo:'/home', pathMatch: 'full'},
  { path:'**', redirectTo:'/home', pathMatch: 'full'}
]

Video:7  =>  Services
-----------
Share data between 2 services


Video:8 => services Data sync with Observable and behavior subject
-----------
$ng g c one
$ng g c two
$ng g service user
inside UserService ->
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
BehaviorSubject help us to front forth between front end and backend communication
need to broadcast to change the value updated by other component
import { Component, OnInit } from '@angular/core';
import { UserService } from '../user.service';

@Component({
  selector: 'app-two',
  templateUrl: './two.component.html',
  styleUrls: ['./two.component.css']
})
export class TwoComponent implements OnInit {
  user;
  constructor(private userService: UserService) { }

  ngOnInit() {
    this.userService.cast.subscribe( user => this.user = user)
  }

}

one.tempalte.html
<input type="text" [(ngModel)] = "editoneUser" > <button (click)="edittheUser()">change</button>
one.component.ts
import { UserService } from '../user.service';
export class OneComponent implements OnInit {
 user:string;
 editoneUser;
  constructor(private userService: UserService) { }

  ngOnInit() {
    this.userService.cast.subscribe( user => this.user = user)
  }
  edittheUser(){
    this.userService.editUser(this.editoneUser)
  }

}

Video:9 => Unit test cases
-----------
unit test, acceptance test e2e test
jasmine, karma, protractor
jasmine  behavior driven
karma help to run test cases in multiple brwoser
jsmine help to do structural code for better performance level

We can able to change the browser testenvironemnt using, karma-firefox-launcher, firefox browser

to install firefox brwoser enable
$npm install karma-firefox-launcher --save-dev

Video:10=> sass(scss), less to your angular project
---------
$ ng new projectName --style=scss
 to change sacc to less

$ng set defaults.stylesheet less -> automatically change the property to less

Video:11 => Angular e2e testi protractor
--------




Ng5- Diff type of routerLink implmentation

Diff type of routerLink implmentation
============================
<nav>
    <a routerLink='/home'></a>
    <a routerLink='/about'></a>
</nav>

case:1
-----
<div *ngFor="let user of userList" [routerLink]="['detail', uer.name]"> {{ user.name }} </div>

case:2
-----
(click)="showUserDetails(user)"

Incase we do the navigation from component function means
 showUserDetails(user){
    this.router.navigate(['user', user.login]);
  }


to make the router navgation implement  routerLink='/home'
If you use parameter passing in router link [routerLink]="['detail', uer.name]"

Sunday 8 April 2018

Angular5 - POC - routing - route params, RxJs Observable with service, tamplate binding, Event binding, Material desing impl

Angular5 POC
============
RxJs Observable with service
tamplate binding, Event binding,
Material desing imple
routing - route params
github link : https://github.com/gnganpath/Angular-6videos-thatJsdude

video:1 -> Installation and requirement software - Local dev environment
----------
Download node js , download and install VS code follow the agular cli version
npm install -g @angular/cli
ng new PROJECT-NAME
cd PROJECT-NAME
ng serve      -> no need of npm install is required here.
ng serve --host 0.0.0.0 --port 4201


video:2 -> component, tempalte binding, Event Handler
----------
bangularbangk$ ng g c circular

inside app.hml - template binding
bind the circular template using <app-circular>

app-circular.html
(click)="changeTextEventHandler()"

app.component.ts
public changeTxt = "initial text";

ngOnInit(){
this.changeTxt = "update text in OnInt";
}

changeTextEventHandler(){
this.changeTxt = "Event handler in child component";
}

video:3 -> Service, Observable, RxJS
----------

bangularbangk$ ng g service github/github

RxJs/Observale ->
app.module.ts
import { HttpClientModule } from '@angular/common/http';
...
imports: [
    BrowserModule,
    HttpClientModule
  ],

github.service.ts
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/map'
@Injectable()
export class GithubService {
  constructor(private http: HttpClient) { }
  getUser(searchText): Observable<any>{             // rxjs - observable call for API
    const url= 'http://api.github.com/search/users?q='+searchText;
    return  this.http.get(url).map(
      res => {
        const data = res;
        console.log(data)
        return data;
      }
    )
  }
}

search.html
<input type="text" (keyup)="onKeyup($event)">
<button (click)="getUsers()">Search</button>
<p>{{ searchCount }}</p>
<ol *ngIf="searchResult">
  <li *ngFor="let user of searchResult.items">{{ user.login }}</li>
</ol>

search.component.ts
import { Component, OnInit } from '@angular/core';
import {GithubService} from '../github/github.service';
 searchText;
  searchResult;
  searchCount;
  ....
  ....
  constructor(private githubService:GithubService) { }
   onKeyup(event){
    this.searchText = event.target.value;
  }
  getUsers(){
    console.log(this.searchText)
    this.githubService.getUser(this.searchText).subscribe(
      res =>{
       // console.log(res)
       this.searchResult = res;
       this.searchCount = res.total_count;
      }
    )};

Video:4 -> Angular2 Material Design

bangularbangk$ npm install --save @angular/material @angular/cdk

app.module.ts
import { MatCardModule } from '@angular/material/card';
....
 imports: [
    BrowserModule,
    HttpClientModule,
    MatCardModule
  ],
 
 
search.html
<div *ngIf="searchResult">
<mat-card class="example-card"  *ngFor="let user of searchResult.items">
  <mat-card-header>
    {{ user.login }}   
  </mat-card-header>
  <img class="profile-image" mat-card-image [src]="user.avatar_url" alt="Photo of a Shiba Inu">
  <mat-card-content>
    content
  </mat-card-content>
</mat-card>
</div>


Video:5 -> Routing, multiple routing, pass a route parameter, load data based on routing
--------

contnents
------------
<base href>
Router imports
Configuration
Router outlet
Router link
Router state
Summary

need to use base-href
index.html
<base href="/">

create appRoutes.ts

import { Routes } from '@angular/router';
import { CircularComponent } from './circular/circular.component';
import { SearchComponent } from './search/search.component';

export const appRoutes: Routes = [
    { path:'circular', component:CircularComponent },
    { path:'search', component:SearchComponent}
]

routeParams implementation in appRoutes.ts

import { Routes } from '@angular/router';
import { CircularComponent } from './circular/circular.component';
import { SearchComponent } from './search/search.component';
import { UserComponent } from './user/user.component';

export const appRoutes: Routes = [
    { path:'circular', component:CircularComponent },
    { path:'search', component:SearchComponent},
    { path:'user/:userId', component:UserComponent}
]
app.module.ts
import { HttpClientModule } from '@angular/common/http';
import { RouterModule } from '@angular/router';
import { appRoutes } from './app.routes';
.....

import: [
RouterModule.forRoot(appRoutes),
BrowserModule,
HttpClientModule
]

app.html


<router-outlet></router-outlet>       <!--  to implement router in our applicaiton -->

goto localhost:4200/search

find one result  and click
search.html
   <button  mat-button (click)="showUserDetails(user)">{{ user.login }}   </button>
  
search.component.ts
import { Router } from '@angular/router';
 showUserDetails(user){
    this.router.navigate(['user', user.login]);
  }

github.service.ts
.....

  getUserDetails(userId):Observable<any>{
    const url  = 'https://api.github.com/users/'+userId;
    return this.http.get(url).map(
      res =>{
        const user = res;
        return user;
      }
    )
  }
 
user.component.ts
import { ActivatedRoute } from '@angular/router';
....
private userDetail;

  constructor( private activatedRouter:ActivatedRoute, private githubService: GithubService) { }

  ngOnInit() {
    const userId = this.activatedRouter.snapshot.params['userId'];
    console.log(userId)
    this.githubService.getUserDetails(userId).subscribe(
      res =>{
        this.userDetail = res;
        console.log(this.userDetail)
      }
    )
  }
 
 
user.html
<h1>User Details page</h1>
<div *ngIf="userDetail">
  <h4>{{userDetail.name}}</h4>
  <p>email : {{userDetail.email}}</p>
  <small>followers: {{userDetail.followers}}</small>
</div>


Video:6 -> pipes, Debug angular 2, build for proeduction
----------
simple default pipes
<h4>{{userDetail.name | uppercase}}</h4>
  <p>email : {{userDetail.email}}</p>
  <small>followers: {{userDetail.followers}}</small>
  <p>created at:{{userDetail.created_at | date }}</p>
 
For Debugging:

Install chrome Augury plugin

 angular tree, state of the compoent, compoennt dependencies



Ref: ThatJsdude

Friday 6 April 2018

Javascript - TicTacToe Game - Dynamic



<html>
<title>Tic Tac Toe</title>
<head>
<style>


*{
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box; 
  box-sizing: border-box;
}

select {
    padding:3px;
    margin: 0;
    -webkit-border-radius:4px;
    -moz-border-radius:4px;
    border-radius:4px;
    -webkit-box-shadow: 0 3px 0 #ccc, 0 -1px #fff inset;
    -moz-box-shadow: 0 3px 0 #ccc, 0 -1px #fff inset;
    box-shadow: 0 3px 0 #ccc, 0 -1px #fff inset;
    background: #f8f8f8;
    color:#888;
    border:none;
    outline:none;
    display: inline-block;
    -webkit-appearance:none;
    -moz-appearance:none;
    appearance:none;
    cursor:pointer;
    width:100px;
}


.minContainer {
    padding: 20px;
    padding-right: 30px;
    position: absolute;
}

table {
    border-collapse:collapse;
    table-layout: fixed;
    border-spacing: 0;
    width:250px;
    height:300px;
    margin-right:5px;
}
.td {
    border: 2px solid #cccccc;
    font-size:20px;
    font-family:"Helvetica Neue", Helvetica, Arial, sans-serif;
    color:#ccc;
    line-height: 1.428571429;
    width: 30px;
    height: 32px;
    min-width: 32px;
    max-width: 302px;
    min-height: 32px;
    max-height: 32px;
    text-align: center;
}

.X{
    background-color: #FF8362;   
}

.O{
    background-color: #BB7365;
}


</style>
</head>
<body onload="fnLoad()">
        <div class="container">
                <div>
                        <select id="grid">
                        </select>
                        <button name="NewGame" class="newGame" value="Start a New Game" onClick="fnNewGame()">Start a New Game</button>
                </div>
                <div class="minContainer">
                        <table class="row" id="game"></table>
                </div>
        </div>
<script>


var turn = 'X';
var score = {
    'X': 0,
    'O': 0
};
var gridValue = 0;

function fnLoad() {
    var select = document.getElementById("grid");
    for (i = 3; i <= 100; i += 1) {
        var option = document.createElement('option');
        select.options[select.options.length] = new Option(i + ' X ' + i, i);
    }

    addEvent(document.getElementById("game"), "click", fnChoose);

    fnNewGame();
}

function addEvent(element, eventName, callback) {

    if (element.addEventListener) {
        element.addEventListener(eventName, callback, false);
    } else if (element.attachEvent) {
        element.attachEvent("on" + eventName, callback);
    }
}

function fnChoose(e) {
    if (e.target && e.target.nodeName == "TD") {
        var targetElement = document.getElementById(e.target.id);
        var prevTurn;
        if ((targetElement.className).indexOf("disabled") == -1) {
            targetElement.innerHTML = turn;
            targetElement.classList.add('disabled');
            targetElement.classList.add(turn);
            score[turn] += 1;
            prevTurn = turn;
            turn = turn === "X" ? "O" : "X";
            if (fndecide(targetElement, prevTurn)) {
                alert(prevTurn + ' has won the game');
                fnNewGame();
            } else if ((score['X'] + score['O']) == (gridValue * gridValue)) {
                alert('Draw!');
                fnNewGame();
            }
        }
    }
}

function fndecide(targetElement, prevTurn) {
    var UL = document.getElementById('game');
    var elements, i, j, cnt;
    if (score[prevTurn] >= gridValue) {
        var classes = targetElement.className.split(/\s+/);
        for (i = 0; i < classes.length; i += 1) {
            cnt = 0;
            if (classes[i].indexOf('row') !== -1 || classes[i].indexOf('col') !== -1 || classes[i].indexOf('dia') !== -1) {
                elements = UL.getElementsByClassName(classes[i]);
                for (j = 0; j < elements.length; j += 1) {
                    if (elements[j].innerHTML == prevTurn) {
                        cnt += 1;
                    }
                }
                if (cnt == gridValue) {
                    return true;
                }
            }
        }
    }
    return false;
}

function fnNewGame() {
    var gameUL = document.getElementById("game");
    if (gameUL.innerHTML !== '') {
        gameUL.innerHTML = null;
        score = {
            'X': 0,
            'O': 0
        };
        turn = 'X';
        gridValue = 0;
    }
    var select = document.getElementById("grid");
    gridValue = select.options[select.selectedIndex].value;
    var i, j, li, k = 0,
        classLists;
    var gridAdd = +gridValue + 1;

    for (i = 1; i <= gridValue; i += 1) {
        tr = document.createElement('tr');
        for (j = 1; j <= gridValue; j += 1) {
            k += 1;
            li = document.createElement('td');
            li.setAttribute("id", 'li' + k);

            classLists = 'td row' + i + ' col' + j;

            if (i === j) {
                classLists = 'td row' + i + ' col' + j + ' dia0';
            }

            if ((i + j) === gridAdd) {
                classLists = 'td row' + i + ' col' + j + ' dia1';
            }

            if (!isEven(gridValue) && (Math.round(gridValue / 2) === i && Math.round(gridValue / 2) === j))
                classLists = 'td row' + i + ' col' + j + ' dia0 dia1';

            li.className = classLists;
            tr.appendChild(li);

        }
        gameUL.appendChild(tr);
    }
}


function isEven(value) {
    if (value % 2 == 0)
        return true;
    else
        return false;
}

</script>       
</body>
</html>