Showing posts with label beginners. Show all posts
Showing posts with label beginners. Show all posts

9/29/16

Redux - the blitz

I have heard a lot about redux but never had time to put my hands on it., so i guess the time is come - lets write something about redux.

So, what is redux?

To put the long terms short - it is a way to organize logic which changes the state (application data) of single page application. So if you asking yourself: is redux about to make me write less code? - Well, the answer is no, this is not the point. The point is - to make clear for developer who and why changed the state of app.

Three Basic Principles Of Redux

According to what the documentation say, three basic principles of redux are:
1. Single source of truth( single store )
2. State is read-only
3. Changes are made with pure functions (reducers)
For implementing the redux into our search app we will use react-redux library.

Lets Talk About Three Primary Modules Of React-Redux

Store

Most important module there all application data (or state) is stored:
initial state:


export default {
    results: [],
    loading: false
}

...
...
...
const rootReducer = combineReducers({
  results: searchResults,
  loading
});

export default rootReducer;

...
...
...
export default function configureStore(initialState) {
  return createStore(
    rootReducer,
    initialState,
    applyMiddleware(thunk, reduxImmutableStateInvariant())
  );
}

Actions

A way by which components can "talk" with store, explaining what exactly gonna happen.
search action:


export function loadResultsSuccess(results) {
  return { type: 'LOAD_RESULTS_SUCCESS', results};
}

export function loadResults(query) {
  return function(dispatch) {
     let url = "https://api.github.com/search/repositories?q="+query+"+language:typescript&sort=stars&order=desc";
     
     return  fetch(url)
        .then(function(response) {
         return response.json();
        })
        .then((result) => {
            let results;
            if (result.items.length !== 0) { 
               results = result.items.slice(0,5);
            } else {
               results = [];
            }
            //DISPATCH RESULTS
            dispatch(loadResultsSuccess(results));
        });
  };
}

Reducers

Should get the info from action and return new state object which generated from the original state, but without mutating it.


import initialState from './initialState';

export default function searchReducer(state = initialState.results, action) {
  switch (action.type) {
    case 'LOAD_RESULTS_SUCCESS':
      return action.results;

    default:
      return state;
  }
}

Make The Appllication To Work With Stuff Was Just Created

Lest modify our SearchPage so, it will dispatch "search" action instead of calling "loadResults" method (which duty was to load the search results from the request and put the to the state):
SearchPage component:


import React, { Component, PropTypes } from 'react'
import SearchBar from './mySearchBar';
import ResultsList from './myResultsList';
import {connect} from 'react-redux';
import {bindActionCreators} from 'redux';
import * as searchActions from './actions/actionSearch';

class SearchPage extends Component {
      constructor(props) {
        super(props)
      }

      handleSearchTextChange(txt) {
        this.props.loadResults(txt);//<---HERE      
      }

      render() {
        const {results, loading} = this.props;
       
        return (
          <div>
            <SearchBar onChange={this.handleSearchTextChange.bind(this)}/>
            <ResultsList results={results} loading={loading}/>
          </div>
        );
      }
};
    

function mapStateToProps(state, ownProps) {
  return {
    results: state.results,
    loading: state.loading
  };
}

function mapDispatchToProps(dispatch) {
  return {
    loadResults: bindActionCreators(searchActions.loadResults, dispatch)
  };
}

export default connect(mapStateToProps, mapDispatchToProps)(SearchPage);   

See the full code on the repo

8/16/16

React - Organizing the project

How To Organize the Project

Yes, we created little app using the react library. For simplicity i used (already removed in latest babel version) browser module of babel-core which compiles the react in the browser. Thats not ideal way of writing react aps(compiling in the browser is heavy operation that can be done using some task running tool instead).

Using Webpack

There are many tools which can do the react compilation job. One of those tools is a well known webpack which we will use for this post

Installing Webpack

For be able to run webpack you must have nodejs installed on your machine.
Lets run this command in the console for install webpack globally


   npm install webpack -g
Now you able to bundle your javascript files into one js file named "bundle.js" with single console command

webpack ./app.js app.bundle.js
Instead of specify parameters in the command line, better attitude is to specify them in wepack.config.js file:

 module.exports = {
     entry: './src/app.js',
     output: {
         path: './bin',
         filename: 'app.bundle.js'
     }
 };
Tha way the command is way more shorter:

webpack //thats it

Dependencies

Since we will create react application we will need to install various dependencies (like babel) which will help us to compile and run our project. It is good practice to store list of dependencies in package.json file, so npm module of nodejs will be able to install them at once using single command npm install.
For creating package.json file run:


npm init 
Will promp you with various questions about your project, currently you may answer "yes" (by pressing ENTER) on all of them. finally package.json file will be created in your root directory.
From now each module we will install - will be listed in the package.json file:

 npm i react react-dom --save
package.json :

{
  "name": "webpack project",
  "version": "1.0.0",
  "description": "",
  "main": "webpack.config.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "react": "^15.3.0",
    "react-dom": "^15.3.0"
  }
}

babel

Since react contains some features that not supported by some browsers (like jsx) we will use babel library:


npm install --save-dev babel-loader babel-core babel-preset-react
So our wepack.config.js file will finally look like:

 module.exports = {

     entry: './src/app.js',
     output: {
         path: './out',
         filename: 'app.bundle.js',
     },
     module: {
         loaders: [{
             test: /\.js?|\.jsx?$/,
             exclude: /node_modules/,
             loader: 'babel',
             query: {
                presets: ['react']
             }             
         }]
     }
 }
Now our project configured in the way so when user runs

webpack
command in the console-
it compiles every javascript (.js) file and it puts the results inside out directory in single file app.bundle.js, isnt that cool?

Project Structure

After we created the minimalistic configuration, lets take a care about files that are part the project itself:
app.js file where we will place our (need to be compiled) javascript code (lets put it in the "src" directory) and index.html - the main html file of our single page app which will refer the compiled results of javascript:


 <!DOCTYPE html>
 <html>
     <head>
         <meta charset="utf-8">
     </head> 
     <body>
         <div id="example"></div> 
         <script  src="out/app.bundle.js" charset="utf-8"></script>
     </body>
 </html>
Now lets paste the app code into the app.js file

var React = require('react');
var ReactDOM = require('react-dom');
var $ = require("jquery");

//Search Bar
var SearchBar = React.createClass({
  
  onChange: function(e) { 
    // console.log(e.target.value)
    this.props.onTextChange(e.target.value);
  }, 
  render: function() {
    return (
      <div><input placeholder="type search term" onChange={this.onChange}/></div>
    );
  }
});   
// Results List
var ResultsList = React.createClass({

  render: function() {
    
      var createItem = function(item, idx) {
        return <li key={idx}>{item.text}</li>;
      };
      var list;
      if(this.props.results && this.props.results.length && !this.props.loading) {
        list = this.props.results.map(createItem);
      } else if(this.props.results.length==0  && !this.props.loading){
        list = 'no items yet';
      } else if(this.props.loading) {
        list = <div className="loader">Loading...</div>;
      }
      return <ul className="results">{list}</ul>;
    
  }
});
//Search Page
var SearchPage = React.createClass({
  getInitialState: function() {
    return {results: [],loading:false};
  }, 
  loadResults: function(query){
    this.setState({loading:true});
    
    var url = "https://api.github.com/search/repositories?q="+query+"+language:typescript&sort=stars&order=desc";
    $.get(url)
    .then(function (result) {
      
      if(result.items.length!==0){ 
        var results = result.items.map(item => { 
          return   {text: item.name}
        }).slice(0,5);
        
      }
      this.setState({loading: false, results:results});
    }.bind(this));//<-- important to bind this for use "setState"
    
  },
  handleSearchTextChange: function(txt){

    this.loadResults(txt)
    
  },
  render: function() {
    return (
      <div>
        <SearchBar onTextChange={this.handleSearchTextChange}/>
        <ResultsList results={this.state.results}  loading={this.state.loading}/>
      </div>
    );
  }
});
    
ReactDOM.render(
    <SearchPage />,
    document.getElementById('example')
);
module.exports = SearchPage;

jquery

the last thing left is to add jquery library to the project


 npm install --save jquery 
After jquery is included and project compiled you can run it with

webpack-dev-server
The developer server of webpack.
Here is link to repo with the code.
Hope you have fun reading

8/13/16

React - Building Search App (Part 6)

Last Finishes

Our app looks great now, but there some more things we could improve:
For example- when the user has not performed any search yet it is good to display no items yet message instead of "some item".
Lets modify Results List component accordingly:


    
     // Results List
    var ResultsList = React.createClass({
 
      render: function() {
        
          var createItem = function(item, idx) {
            return 
  • {item.text}
  • ; }; var list; if(this.props.results && this.props.results.length) { list = this.props.results.map(createItem); }else{ // <--- no search results came from server list = 'no items yet'; } return
      {list}
    ; } });

    Displaying loading animation

    It is good practice to display animation when request sent but results hasn't come back yet.
    That way user will notified that his actions were noticed and the the server working to fulfill his request.
    That means we should pass another property from SearchPage to ResultsList component - loading which will "tell" the results component when request started and when it finished (e.g. when to show loading animation):

    
    
         loadResults: function(query){
            if(query==''){
              this.setState({
                loading: false, 
                results:[]
              });
              return;
              
            }
            
            this.setState({loading:true}); // <--- the request started so animation must be visible
            var results = [];
            
            var url = "https://api.github.com/search/repositories?q="+query+"+language:typescript&sort=stars&order=desc";
            $.get(url)
            .then(function (result) {
             
              if(result.items.length!==0){ 
                results =result.items.map(item => { 
                  return   {text: item.name}
                }).slice(0,5);
                
              }else{
                results = []
              }
             this.setState({loading: false, results:results});
            }.bind(this));//<-- important to bind this for use "setState"
            
          }
           ...
           ...
           ...
          render: function() {
            return (
              <div >
                 <SearchBar onTextChange={this.handleSearchTextChange}/ >
                 <ResultsList results={this.state.results}  loading={this.state.loading}/ > //<---passing loading property to ResultsList component
               </div >
            );
          }
    

    Animation

    i will add to project the CSS code i took from this awesome project so it will display spinner animation:

    
    
    .loader {
      margin: 20px auto;
      font-size: 10px;
      position: relative;
      text-indent: -9999em;
      border-top: 1.1em solid rgba(6,178,103, 0.2);
      border-right: 1.1em solid rgba(6,178,103, 0.2);
      border-bottom: 1.1em solid rgba(6,178,103, 0.2);
      border-left: 1.1em solid #06b267;
      -webkit-transform: translateZ(0);
      -ms-transform: translateZ(0);
      transform: translateZ(0);
      -webkit-animation: load8 1.1s infinite linear;
      animation: load8 1.1s infinite linear;
    }
    .loader,
    .loader:after {
      border-radius: 50%;
      width: 5em;
      height: 5em;
    }
    @-webkit-keyframes load8 {
      0% {
        -webkit-transform: rotate(0deg);
        transform: rotate(0deg);
      }
      100% {
        -webkit-transform: rotate(360deg);
        transform: rotate(360deg);
      }
    }
    @keyframes load8 {
      0% {
        -webkit-transform: rotate(0deg);
        transform: rotate(0deg);
      }
      100% {
        -webkit-transform: rotate(360deg);
        transform: rotate(360deg);
      }
    }
    
    
    After adding the animation css, we need to modify the ResultsList component code so it will be able to display the animation:
    
        // Results List
        var ResultsList = React.createClass({
     
          render: function() {
            
              var createItem = function(item, idx) {
                return <li key={idx}>{item.text}</li>;
              };
              var list;
              if(this.props.results && this.props.results.length && !this.props.loading) {
                list = this.props.results.map(createItem);
              } else if(this.props.results.length==0  && !this.props.loading){
                list = 'no items yet';
              } else if(this.props.loading) {
                list =  <div className="loader">Loading... </div>;
              }
              return  <ul className="results">{list} </ul>;
            
          }
        });
    

    Now the animation is displayed

    the code on plnkr
    Hope you have fun reading

    3/27/16

    Using Promises In Angular2

    In the last post we created our first angular service. This service served only some static data for chart componentt we build in previous posts.
    Everybody knows that to serve static data is not cool.
    The really though guys use services for bring data from server.
    In other words - real service must use is promises.

    Promises In Angular2

    For one who used promises in angular 1. to use promise in angular2 is pretty simple:

    
    @Injectable()
    export class FlotService {
      getFlotEntries() {
        return Promise.resolve(FlotEntries);
      }
    }
    
    
    Yes, the same old good Promise.resolve. And for consume the service we should use the same old "then"
    
    export class App implements OnInit {
      
      private dataset:any;
      public entries;  
      getEntries() {
        this._flotService.getFlotEntries().then(
                           entries => this.dataset[0].data = entries,
                           error =>  this.errorMessage = error);
      } 
    
    
    Now lets make our chart component to work with this service.

    Projecting data into component

    The issue i had run into is that while the call to the service is on the main "App" component, the place i want data to be displayed is on the inner component - "Flot", which getting chart "data" property as input parameter:

    
    <flot  [options]="splineOptions" [dataset]="dataset" height="250px" width="100%"></flot>
    
    
    In angular 1. all data changes are observed and immediately projected after the change is located by digest cycle.
    In angular2 - not in all cases. Angular2 change detection doesn't observe the content only the value or reference itself (angular2 observes only "dataset" but not inner property "data")

    A workaround

    One way to make angular2 to watch the inner properties changes is to use ngDoCheck().
    ngDoCheck() is called every change detection cycle, whether or not there are any input property changes.(great thanks to these guys for this information)
    Now we need to modify flot component - so it start to use OnChanges:

    
    import {Component, ElementRef, Input} from 'angular2/core';
    
    @Component({
      selector: 'flot',
      template: `
    loading
    ` }) export class FlotCmp{ ... ngOnInit() { if(!FlotCmp.chosenInitialized) { let plotArea = $(this.el.nativeElement).find('div').empty(); plotArea.css({ width: this.width, height: this.height }); $.plot( plotArea, this.dataset, this.options); FlotCmp.chosenInitialized = true; } } ngDoCheck() { if(this.dataset[0].data !== null && !this.dataPlotted) { console.log('plotting data'); let plotArea = $(this.el.nativeElement).find('div').empty(); $.plot( plotArea, this.dataset, this.options); this.dataPlotted = true; } } }
    Now the child component view reacts to changes of flot data

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

    2/23/16

    Using Angular2 Services

    Remember we created flot component in previous posts?
    Lets have a quick look on the code now:

    
    export class App {  
      constructor() {
        ...
        //Look here - dont you feel something here is uuuugggglllyyyy?
        this.dataset = [{label: "line1",color:"blue",data:[
        [1, 130],
        [2, 40],
        [3, 80],
        [4, 160],
        [5, 159],
        [6, 370],
        [7, 330],
        [8, 350],
        [9, 370],
        [10, 400],
        [11, 330],
        [12, 350]
    ]}];
      }
    }
    
    
    The way dataset property sat - is perfect example of hardcoding, and everybody knows that hardcoding is bad.
    Since we dont have real server to get data from yet, at least lets move the data-getting logic to some different module, in other words -

    Lets Create A Service

    
    export var FlotEntries: Array[] = [
        [1, 130],
        [2, 40],
        [3, 80],
        [4, 160],
        [5, 159],
        [6, 370],
        [7, 330],
        [8, 350],
        [9, 370],
        [10, 400],
        [11, 330],
        [12, 350]
    ];
    
    //@Injectable()
    export class FlotService {
      getFlotEntries() {
        return FlotEntries;
      }
    }
    
    
    This service doing only one thing - getting data for a plot chart.

    Lets Use Our Service

    Last thing that left - is to teach our main component how to use the service:
    Note: Dont forget to list the service inside "poviders" property

    
    //our root app component
    import {Component} from 'angular2/core'
    import {FlotCmp} from './flot';
    import {FlotService} from './FlotService';
    
    @Component({
      selector: 'my-app',
      providers: [],
      template: `
        <div>
          <flot  [options]="splineOptions" [dataset]="dataset" height="250px" width="100%"></flot>
        </div>
      `,
      directives: [FlotCmp],
      providers: [FlotService]//important!!!
    })
    export class App {
      
      constructor(private _flotService:FlotService) {
        this.name = 'Angular2'
        this.splineOptions: any = {
                series: {
                    lines: { show: true },
                    points: {
                        radius: 3,
                        show: true
                    }
                }
        };
        this.dataset = [{label: "line1",color:"blue",data:this._flotService.getFlotEntries()]}];
      }
    }
    
    

    Looks better isn't it?
    plunkr
    Thats it, now you know how to create angular2 service.
    Hope you have fun reading

    2/6/16

    bootstrap collapsible directive in angular2

    I decided to to take another looking easy challenge - to make collapsible directive with angular2 by myself.
    I will use css of great bootstrap framework.
    Bootstrap framework has collapsed CSS class for make elements disappear (by applying "display:none" style), and "in" class, which when it set on collapsed element - makes it to show up.
    So, once we already know (after doing couple of things in previous posts) how to create some angular2 components -

    Lets create parent component (App)

    
    //our root app component
    import {Component} from 'angular2/core'
    import {Collapse} from 'src/collapse'
    @Component({
      selector: 'my-app',
      providers: [],
      template: `
        <div>
          <h2 (click)="isCollapsed = !isCollapsed">click here</h2>
           
          <div class="collapse in" [collapse]="isCollapsed" >
            <div class="well">
              panel panel panel
            </div>
          </div>
          
        </div>
      `,
      directives: [Collapse]
    })
    export class App {
      isCollapsed:boolean = false;
      constructor() {}
    } 
    
    

    Directive is not dead

    Yes there are directives in angular2 too. Their goal is to be decorator-style directives, which do not have templates. According to angular2 documentation "directive changes the appearance or behavior of a DOM element."
    Note that for changing class property of directive's root element i go to use HostBinding factory
    
    import {Directive, Input, HostBinding} from 'angular2/core'
    @Directive({selector: '[collapse]'})
    export class Collapse { 
     
    
      @HostBinding('class.in') 
      private isCollapsed:boolean;
      
      
      @Input()
      private set collapse(value:boolean) { 
         
          if(!value){   
            this.isCollapsed = true; 
          }else { 
            this.isCollapsed = false; 
          }
         
      }
      constructor() {}  
    }
    
    

    Animation

    Everybody knows that collapse is not looking cool without animation.
    Everyone who little familiar with css, knows that for make animation you may use CSS3 Transitions.
    For example:

    
    .collapsing{
     height:80px; 
     overflow:hidden;
     transition:height 0.4s ease-in-out;
    }
    
    
    After applying this class on some element, its height will smoothly change to 80 pixels.

    Trick

    Animation will not work for elements those height is not specified (auto). So, for make some html elements to collapse with animation we must give them their own initial css height. One of the ways to measure the actual height of the element - is to use scrollHeight property.
    
        this.h = elem.scrollHeight;   
    
    

    Lets use the trick on our the directive

    
    import {Directive, Input, HostBinding, ElementRef} from 'angular2/core'
    @Directive({selector: '[collapse]'})
    export class Collapse { 
    
      @HostBinding('class.collapsing') 
      private isCollapsing:boolean   
    
        // style
      @HostBinding('style.height') 
      private height:string;
      
      
      @Input()
      private set collapse(value:boolean) { 
        if(value!==undefined){
          if(value){ 
            this.hide(); 
          }else { 
            this.show();
          }
        }
        //
      }
      constructor(public el: ElementRef) {
        
        this.measureHeight(); 
      }  
      measureHeight() {
        let elem = this.el.nativeElement;
        //lets be sure the element has display:block style
        elem.className = elem.className.replace('collapse', '');
        this.h = elem.scrollHeight;
       
      }
      hide(){
        this.height = this.h +'px'
        setTimeout(() => {
            this.height = '0px';
            this.isCollapsing = true;//apply 'collapsing' class
        },1); 
      }
      show() {
        this.height = '0px'
        setTimeout(() => {
            this.height = this.h + 'px';
            this.isCollapsing = true;//apply 'collapsing' class
        },1);
      }  
    }
    
    

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

    1/13/16

    Building my first directive with angular2

    Recently i started to play with recently released beta of angular2.
    I'm totally beginner and i want to build very simple thing.
    I want to build the component (component is like directive in angular 1.) that displays current time in format given as a parameter (through the attribute format).
      
      
        <now format="'h:mm:ss'"></now>
      
    
    When rendered HTML, should look like this:

    How to run angular2?

    First thing you need then you want to run angular2 is environment.
    You can use one of angular2 starter kits like this one Or just open plunker and select "Editor" -> "New" -> "AngularJs" -> "2.0.x TS" and viola!! you are angular2 programmer!


    Component

    The first basic thing in angular2 is component, so: Lets create a component:
    
    
    import {Component} from 'angular2/core'
    
    @Component({
      selector: 'now',
      template: `

    {{date}}

    ` }) export class Now { private date; constructor() { this.date = new Date(); } }

    Yoo hoo!!! The component created and running!!!
    And it displays the current date!!!
    But one little disturbing thing is that date appears raw , which is little bit ugly...

    So lets improve the component by formatting the output.


    Pipe (Filter)

    Like in sngular 1. there are filters in angular2, they called pipes

    
    import {Component} from 'angular2/core'
    
    @Component({
      selector: 'now',
      template: `

    {{date | date :'dd/MM/yyyy'}}

    ` })

    Getting value from attribute (The tricky part)

    As we already said the desired format should be passed through the attribute. But how to access this attribute from inside component constructor? Fortunately there is Attribute module which enables you to inject attribute into constructor parameters:
    
    import {Component, Attribute} from 'angular2/core'
    export class Now {
       private date;
       
      constructor(@Attribute("format") format) { 
        this.format = format;
        this.date =  new Date(); 
    
      } 
    
    } 
    
    

    Better way

    After Lenin's older brother was executed because he tried(but failed) to kill king of Russia with bomb, young Lenin said "We will go different way"...
    After looking at angular2 docs i found better (more angular2mish) way which says that if we want to pass attribute to component we must use square brackets :

      
      
        <now [format]="'h:mm:ss'"></now>
      
    

    I will use @Input module instead of @attribute

    
    
    
    import {Component,  Input} from 'angular2/core'
    
    @Component({
      selector: 'now',
      template: `
          

    {{date | date: _format}}

    ` }) export class Now { private date; @Input() set format(formatName:string){ this._format = formatName; } constructor() { this.date = new Date(); } }

    How to update time each second?

    Little nice thing to add here is ability to update the time displayed in directive each second. For achieve this i'm using ES6 fat arrow syntax
    
    
    export class Now {
       private date;
       @Input() set format(formatName:string){
         this._format = formatName;
       
       }   
      constructor() { 
        this.date =  new Date(); 
        
        setInterval(() => {
            this.date =  new Date();
         }, 1000);
      } 
    
    } 
    
    

    View it on plunker:

    11/25/13

    Starting with gitHub

    What are you need to start  use github?
    Not much...
    1. Install github client (for windows)
    2. after installing go to AllPrograms >GitHub > git shell
    3. git console should appear.
    Now, after you have git installed, lets start with some basic operations:
    To get the code from remote repository to local:
    1. browse to some directory where you want your local repository to be

    2. type: git clone https://github.com/someuser/YOUR_REPO_NAME.git
    If all the things is correct - the local repository with all its contents should create.

    Congratulation! you just became a git user

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