Sunday, May 14, 2017

Angular v4 (or) call it just "Angular"

This blog is a high level gist of Angular 4 features. For detailed explanation refer to my article in DNC magazine. Article is titled "Angular 4 application development with Bootstrap 4 and TypeScript". Follow this link to download the magazine for free.


In December 2016, in an NG-BE (Angular Belgium) keynote, Igor Minar talked about Angular’s release schedule and upcoming features. In the process, he announced plan for a major release in March 2016 - “Angular 4”. Angular team decided to skip a major version number 3.

Why not Angular 3? - MonoRepo: Angular 2 has been a single repository, with individual packages downloadable through npm with @angular/package-name convention. For example @angular/core, @angular/http, @angular/router so on. Considering this approach, it’s important to have consistent version numbers among various packages. Angular router has already been on version 4. Hence, Angular team skipped a major version 3. It will help avoid confusion with certain parts of the framework on version 4 and the others on version 3.

If there were any apprehensions about Angular 4, could be due to baggage of scale of transition between Angular 1.x and 2.x. Considering Angular was moving from MV* (Model View Whatever) pattern to components focused approach, the framework features were very different and caused many applications to rewrite major parts of their code base.


However, between v2.x and v4 it is a very different story. It is a progressive enhancement. Majority of changes are non-breaking. 

Angular 4 is out on 23rd March ’17. Consider the following enhancements,
  • The release has considerable improvements in bundle size. Some have reported up to 60% reduction in Angular bundles’ file size.
  • The ngc, AOT compiler for Angular and TypeScript is much faster.
  • Angular 4 is compatible with TypeScript’s newer versions 2.1 and 2.2. TypeScript release helps with better type checking and enhanced IDE features for Visual Studio Code. The changes helped the IDE detect missing imports, removing unused declarations, unintentionally missing “this” operator etc.

Get Started with an Angular 4 project using Angular CLI

The latest version of Angular CLI (v1.0) is already scaffolding with Angular 4. If you are using an older version, upgrade Angular CLI. A new project created using Angular CLI references Angular 4. Refer to figure 1. 

To upgrade Angular CLI, run following commands,

npm uninstall -g angular-cli
npm cache clean
npm install -g angular-cli@latest

To create a new project with Angular CLI run the following command
ng new my-project-name

Figure 1 Version details for various libraries with ng -v command

What are the new features in Angular 4?

Note: Refer to this link for code samples.  These samples were built for article in DNC magazine. You may refer to the detailed article in the magazine

Template changes to ng-template

If you are upgrading from Angular 2.x to Angular 4, all template elements have to change to ng-template. Following code will result in a warning.
  <template [ngIf]="isVisible"> Conditional statement </template>

Template parse warnings: The <template> element is deprecated. Use <ng-template> instead

Refactor it to
<ng-template [ngIf]="isVisible"> Conditional statement </ng-template>

Angular *ngIf/then/else

With Angular 2 we could use *ngIf directive to conditionally show a section of the template. With Angular 4, support for else has been added. Consider the following template code
<div *ngIf="isTrue; else whenFalseTmpl">
      <span>I show-up when isTrue is true.</span>
</div>

<ng-template #tmplWhenFalse > I show-up when isTrue is false </ng-template>

When isTrue value is true, instead of showing the span inline, we could offload to another template.
<button class="btn btn-primary" (click)="toggle()"> Toggle </button>
<div *ngIf="isTrue; then tmplWhenTrue else tmplWhenFalse"></div>
<ng-template #tmplWhenTrue >I show-up when isTrue is true. </ng-template>
<ng-template #tmplWhenFalse > I show-up when isTrue is false </ng-template>

Working with Observables and *ngIf/else

While rendering an observable on a template, we can show loading message or a spinner gif with the *ngIf directive. Specify else template to show while async observable is not ready with data. The directive also supports creating a local variable. Notice a local variable dino (let dino) to refer the async object. Consider following code.
<!—show else template “working” while loading observable with data. Notice async filter for dino observable -->

  <div *ngIf="dino | async; else working; let dino">
    <div class="card col-8">
      <div class="col-4">
              <img class="card-img-top" src="assets/images/{{dino.name}}.png" [alt]="dino.name">
      </div>
      <div class="card-block">
        <h4 class="card-title">{{dino.name}}</h4>
<!--removing dinosaur card details for readable snippet. Refer to code sample for complete code. -->
    </div>
    <!-- card end -->
  </div>
  <ng-template #working>
    <div>Loading...</div>
  </ng-template>

In the sample, to mimic delayed loading, the component calls next() on an observable subject after four seconds. Refer to following code snippet,
    this.dino = new Subject<any>();
    // to mimic delayed loading the component calls next on observable subject after four seconds. 
    setTimeout( () =>
     this.dino.next(dataset.dinosaurs[Math.round((Math.random() * 5))])
    , 4000);

Angular Animations

In Angular 2.x, animations were part of @angular/core. It was part of the bundle even if application doesn’t use animations. With Angular 4, animations related artifacts have been moved out of @angular/core. It helps reduce production bundle size. To use animations import BrowserAnimationsModule from @angular/platform-browser/animations. Reference the module in imports array of @NgModule

Angular future release schedule

Refer to the major release schedule below. The details are quoted from this link. Please keep a tab on the page for any changes to the schedule.

Tentative Schedule after March 2017

Date
Stable Release
Compatibility*
September/October 2017
5.0.0
^4.0.0
March 2018
6.0.0
^5.0.0
September/October 2018
7.0.0
^6.0.0
Release schedule taken from AngularJS blog https://github.com/angular/angular/blob/master/docs/RELEASE_SCHEDULE.md

Conclusion

Angular went through good amount of transition from Angular 1.x, MV* model to the framework we know today. The purpose of the transition is to effectively support new features in JavaScript. When used with TypeScript, it is that much more powerful with support for types, integration with IDE like Visual Studio Code and many other features.

In the process, Angular 2 upgrade included many breaking changes. However, upgrading to future versions of Angular are expected to be smooth with minimal or no breaking changes. Framework will continue to evolve to support more features and make developers job easy. It is a good thing. Obviously we do not want a stagnated framework.

References and useful links

Refer to this link for code samples used for the article in the DNC Magazine.
DotNet curry website - http://www.dotnetcurry.com/
For more about Angular CLI NPM repo with documentation, follow the link https://www.npmjs.com/package/angular-cli
Following the link for Angular 4 release notes - http://angularjs.blogspot.in/2017/03/angular-400-now-available.html


Monday, February 20, 2017

Angular CLI gotchas on Windows machine.

Blogger: V. Keerti Kotaru . Author of Angular Material book 

I've attempted to install Angular CLI on a Windows 7 machine. Unlike on a Mac machine, it wasn't seamless. Here are the problems I've encountered and the solutions I found after a little bit of Googling! 

If you are new to AngularCLI, it helps setup a new Angular 2 project and scaffold components, providers etc (as we continue to develop on the project). It is a big time saver.

Angular CLI installation

Angular CLI Github page (link) documents installation with the following step. If your machine has the latest versions of Node, NPM and other prerequisites, this is all you need. You can start using AngularCLI.

npm install -g @angular/cli

However, if you are like me, following are some of the issues and solutions. This is a quick troubleshooting guide. The resolutions were applied on a Windows 7 machine.

Node Version:

Review your node version. Angular CLI and Angular 2 project need node version 6.9.0 or above. Run the following to review if you need to upgrade Node.

npm --version

To upgrade, open a command prompt as an administrator and run the following command

npm install -g n

Missing Python & node-gyp

To install Angular CLI, we need Python and node-gyp. If you encounter a problem running build step during the install, try the following.

Open command prompt as an administrator

npm install -g --production windows-build-tools

Once Windows Build Tools are installed, npm install Angular CLI again,

npm install -g @angular/cli

Verify installation

ng --version

If all is well, you should see version number. See figure 1.

Figure 1: Angular-CLI installed successfully


What are Windows Build Tools?

Windows Build Tools provides a tool-set for compiling native node modules. It includes node-gyp which is a cross-platform compiler for node modules. The Windows Build Tools also include Python. It installs Python and makes it available globally on the Windows machine.

References

Stackoverflow thread - http://stackoverflow.com/questions/3701646/how-to-add-to-the-pythonpath-in-windows-7

Windows Build Tools, NPM package - https://www.npmjs.com/package/windows-build-tools

Angular CLI GitHub page- https://github.com/angular/angular-cli#installation

Friday, January 20, 2017

CSS and styling options in ReactJS

Blog describes approaches for styling ReactJS components
Blogger: V. Keerti Kotaru . Author of Angular Material book 

ReactJS provides multiple options for styling components. We might use traditional approach to have a style-sheet in the project; Then apply CSS classes for elements in the component. Or we might pick a contentious approach to code styles within the component.

I played with following approaches so far,

 a) Specify CSS class in VDOM with className attribute.
 b) Use style object.
 c) Styled-Components

Refer to the complete code samples at this link.

Using className attribute

Use className attribute in the component to use a pre-existing CSS class. Consider following code, it applies two CSS classes alert and alert-info on the div. These are bootstraps alert styles. Refer to figure-1 to see the resultant information alert.

<div className="alert alert-info"> 
  <strong>Hello! Namaste. à¤¨à¤®à¤¸्ते.  à°¨à°®à°¸్à°•ాà°°ం. </strong>
</div>
Figure 1 - rendered output for the code sample 
As we package the code as a React component, we could take advantage of showing the alert as an information or as an error. The component could dynamically apply CSS class based on props set by container component. Consider following code that sets alert-danger style when error prop is set (refer to figure 2). If not the default information styling is applied.

---------- alert.js ---------------------
import React from 'react';

export default (props) => {
  

    // if props.error is true set "alert-danger" else "alert-info".
    return (

        <div className={`alert ${props.error?'alert-danger':'alert-info'}`}>  
           <strong> {props.children} </strong>
        </div>
    )
};

Note: In the expression className={`alert ${props.error?'alert-danger':'alert-info'}`} first set of  braces - {} are React expression and the second set ${} are ES6 string extrapolation syntax. It represents alert-danger or alert-info depending on props.error value (true/false).

Usage:
import Alert from './Alert.js';

          <Alert error>Oops! There is a problem</Alert>
          <Alert>This is an information message</Alert>

Figure 2 - Error alert as error prop is added

Using Style attribute

Similar to className, style attribute could also be used in VDOM. This approach encapsulates style within the component. We are not using a global, pre-existing style.

Provide a JSON object with style values that translate to CSS styles. Consider following code sample and the styleInline variable.

import React from 'react';

export default (props) => {
    let styleInline = {
        fontFamily: 'comic sans ms',
        fontSize:'14px'
    };

    return(
        <div style={styleInline}>
            {props.children}
        </div>
    );
}

Note that styles like font-size need to be written as fontSize in VDOM.

Similar to earlier sample, we can use ES6 string extrapolation to dynamically set a style. Following code changes font-size, font-weight and color based on prop - important.

    let styleInline = {
        fontFamily: 'comic sans ms',
        fontSize:`${props.important?'18px':'14px'}`,
        fontWeight: `${props.important?'bold':'normal'}`,
        color: `${props.important?'red':'gray'}`
    };



Figure 3- result with important prop

Styled Components

Styled components library allows creating and wrapping components with given styles. It makes it easy to implement themes and variation in styles. It eliminates boilerplate code and we can instantly create styled components with quick CSS style text.

Getting started
  • Install styled components using npm
npm install --save styled-components
  • import styled from 'styled-components'
Consider following example. Here a styled component is created with HTML element and styles put-together. 

export let TitleText = styled.h1 `
    margin: 1em;
    font-size: 20pt;
    border: 2px solid cyan;
    background-color: gray;
    color: white;
    padding: 0.5em 1em;  
` ;

// Use the component. See figure 4 for result.
<TitleText>Sample styled component out of H1</TitleText>

Figure 4 - Styled component created out of H1

Like earlier examples, based on props, we can dynamically change certain styles. Following sample changes background and border if a primary prop is set on the component.

export let TitleText = styled.h1 `
    margin: 1em;
    font-size: 20pt;
    border: 2px solid ${props => props.primary?'darkblue':'black'};
    background-color: ${props => props.primary?'darkblue':'gray'};
    color: white;
    padding: 0.5em 1em;  
` ;


// Use the component as below. See figure 5 for result (Without primary attribute, result will be same as figure 4)
<TitleText primary>Sample styled component out of H1</TitleText>
Figure 5 - styled component with prop value primary







The API could also be applied on React components (similar to HTML elements). Consider following simple component.

-----------  Button.js ----------------
import React from 'react';

export default (props) => {
    return (
       <button className={`${props.className} btn`}>{props.text || props.children}</button>        
    )
}

Wrap the component using Styled Component.

import ButtonStatelessComponent from './Button.js';
import styled from 'styled-components';

export let SelfStyledButton = styled(ButtonStatelessComponent) `
                        background: ${props => props.primary?'darkblue':'lightgray'};
                        color: ${props => props.primary?'cyan':'black'};
                        font-size: 18pt;
                        margin: 1em;
                        padding: 0.25em 1em;
                        border: 2px solid lightblue;
                        border-radius: 3px`;

Usage: 
          <SelfStyledButton primary text="Primary Button" />

          <SelfStyledButton> Default button </SelfStyledButton>
Notes: 
  • Primary attribute adds dark blue background and cyan text color.
  • For styling to apply, the component should have className attribute defined as following. This is because, the API creates a CSS class and applies on the component at the given HTML element.
className={`${props.className}

Refer to figure 6 for results.

Figure 6 - Apply primary prop for a primary button. Default button uses component as is.

References and further reading

Friday, December 16, 2016

Using Flow types with React components

Continuing series on Flow, in this blog I'm writing about Flow with React. It details advantages of using Flow while building React components.
Blogger: V. Keerti Kotaru . Author of Angular Material book 

Flow is a natural choice for adding types to a React component. It's primarily because Flow and React are both Facebook's open source projects and community is expected to have better traction in that space. Having said that Typescript is a real contender. It is certainly a viable solution to add types to React components and JavaScript. Will plan to write about Typescript with React in future. To read basic details on Flow, a static type checker for JavaScript check out my earlier blogs,  
1. Idiomatic JavaScript with Flow  
2.Working with Flow on Visual Studio Code 

Type checking is not new to React components. PropTypes are often used for Props' validation. Following are couple of advantages with Flow instead of PropsTypes validation
  • Flow adds type validation for entire JavaScript code. Not just Props on a component. PropTypes validation is specific to Props.
  • Workflow - PropType validation errors are normally seen on console. On the other hand Flow extensions for IDEs show validation errors in-line with the code. It's easy to notice type validation errors.
  • Certain validations are detailed with Flow. For example, a validation that a prop is a function could be done with React.PropTypes.func. But Flow can validate return type and parameter types.

Pre-requisites

Install Flow NPM package. Assuming an NPM package is setup for your code repo, install Flow as a dev dependency on the project.

npm install --save-dev flow-bin

(Or install it globally on the machine)

npm install -g flow-bin

Getting Started with Flow for a React application

If you are using babel transpiler for React, you are all set. A Babel plugin babel-plugin-transform-flow-strip-types would remove types while transpiling. It will be installed along with the package babel-preset-react. React projects using Babel would it include it already.

In the Babel configuration file .babelrc  "presets" configuration and value "react" would run the plugin babel-plugin-transform-flow-strip-types

Code Sample

For simplicity I chose counter component. Checkout code sample at this path.  The counter increments or decrements a value every time you click on a button.

For comparison use this link to review a similar component with PropTypes for validating props.

The sample component expects a prop offset. It has a default value 1. Every time + or - button is clicked, would increment or decrement the value by 1. While invoking the component the offset could be provided as a prop, which will override the default value.

Consider following PropType validations

Counter.propTypes = { 
    offset: React.PropTypes.number 
}; 

// default value provided as below. 
Counter.defaultProps = {
    offset: 1
};

Using Flow types for Props

With Flow we can create a type alias for Props as below,
type CounterProps = { 
 offset: number; 


Specify type for the props variable on the constructor

// declare a class variable props of type CounterProps
props: CounterProps

constructor(props: CounterProps){ 
 super(props); 
 // ... 
}

// declare static variable for default props. 
static defaultProps: CounterProps;

// Now that type system is expecting defaultProps on the class, provide a value.
Counter.defaultProps = {
    offset: 1
};

Functions on props

Consider following code snippet. Every time increment or decrement event occurs, a function callback is provided to containing component. In the sample, containing component prints a string with counter data to console. The callback is invoked/called by Counter component

--------------------- main.js ---------------------------

    // While rendering counter print detailed string with time stamp provided by Counter component and counter value.
    ReactDOM.render(
        <Counter offset={4} eventCallback = {(num: number, eventTime: Date) => 
console.log(`At ${eventTime.toString()} Counter Value is ${num} `)} />
        , document.getElementById('reactApp'));

--------------------- Counter.jsx ---------------------------------------
// Counter props with optional eventCallback function declaration. Notice Maybe type highlighted
 type CounterProps = {
    offset: number;
    eventCallback?: (num: number, eventTime: Date) => void;

};


    // While invoking the callback, as the prop is optional, need to verify it's not null.
    increment(): void{
        this.setState({counterValue: this.state.counterValue + this.props.offset});

        // call provided callback function when increment and decrement events occur.
        // While invoking the callback, as the prop is optional, 
        // need to verify it's not null.
        if(this.props.eventCallback != null){
            this.props.eventCallback(this.state.counterValue, new Date());
        }
    }


The callback is an optional parameter. (Notice the ?). Hence Flow enforces null check before using the function.


References and useful links


Flow for React, official documentation - https://flowtype.org/docs/react.html#_


Tuesday, December 6, 2016

Working with Flow on Visual Studio Code

Blog describes what I believe is an optimal development setup with Flow. It details using Visual Studio Code IDE with Flow.
Blogger: V. Keerti Kotaru . Author of Angular Material book 

Flow is a static type checker. For an introductory blog on Flow's type checking, read my earlier blog.

Optimal way to run type checking with Flow.

Figure 1: Flow process in the background
Primary option for type checking with Flow is to run flow in a command prompt or terminal. In VS code, you may use the integrated terminal (Ctrl + `). Flow will expect .flowconfig file at the root directory. If you are starting with Flow for the first time, run flow init to create the configuration file.

Flow will start a process (if not running already) and type checks only the JS files annotated with // @flow. Then-on, next time flow command is run, type checking will be incremental and hence it will be better performing. 

However, if you need to type check all files use flow check --all. It will start a new process and type checks all files (irrespective // @flow comment is written or not). As it starts a new process, even the ones not modified after previous type checking are checked again. It is not advisable to run every time with the --all option.

Visual Studio Code.

Ever since Visual Studio Code has been launched I've been using it extensively for JavaScript development. It's light weight & launches fast, got an integrated terminal or command prompt for running, npm, grunt or gulp tasks. It's available on both Windows and Mac machines. It has rich set of extensions for all utility actions. You may prefer to use extensions instead of typing in commands in terminal

For Flow's type checking, I'm currently using "Flow Language Support" published by Flowtype . Follow this link to view and download the extension.

Flow extension points out errors inline with the code. JavaScript files annotated with // @flow comment on top of the page are type checked. Use Problems Window or move the mouse over error to see details on each error. See figure2. Status bar shows error/warning count, click on which brings up the problems window.

Figure 2: VS Code's extension for Flow shows errors with type checking
Note: The above extension starts Flow background process once the window is launched. It incrementally type checks new files.

Skip JavaScript and Typescript syntax checking in VS Code.

In VS Code Flow and the default Typescript or JavaScript syntax checks could conflict. Use the following configuration to disable default checks.

Errors due to conflict with Typescript
"javascript.validate.enable": false,
"typescript.validate.enable": false

Go to Preferences >> Workspace Preferences (or User Preferences) and provide the configuration in settings.json. 

Note: Updating the configuration in Workspace preferences would skip JS and Typescript checking in only the current project. Updating it in User Settings will skip for all projects.

The workspace settings could be checked-in to git or any other source control. The settings are saved in settings.json under .vscode folder at the root directory. This will allow all developers on the project obtain settings by default. We don't have to do it on each machine explicitly.

References and useful links.

VS Code extension for Flow - https://marketplace.visualstudio.com/items?itemName=flowtype.flow-for-vscode
Documentation on starting a new Flow project - https://flowtype.org/docs/new-project.html#_

Thursday, December 1, 2016

Idiomatic JavaScript with Flow

This blog describes Flow, a static type checker for JavaScript. It provides getting started details and basic concepts of type checking using Flow.
Blogger: V. Keerti Kotaru . Author of Angular Material book 

What is Flow?

Flow is a static type checker for JavaScript. It is an open source project by Facebook (GitHub link). It enables specifying types for variables and objects in JavaScript.

Flow type checking could be run on a console. Easier option is to use plug-ins or extensions with IDEs. I use Visual Studio Code for JavaScript development. I find Flow Language Support extension by Flowtype publisher pretty useful. Follow the link to view and install it.

How does it work?

Specifying types for JavaScript variables and objects could be useful as they point out common code errors that could result in bugs. However, browsers do not understand flow syntax and type annotations. Flow types need to be stripped off before running on the browser. And hence Flow is a static type checker, rather than a language.

Setup Flow

Assuming an NPM package is setup for the sample code repo, install Flow using as a dev dependency on the project.

npm install --save-dev flow-bin 

We may use Babel plug-in to strip off types. But for simplicity, in this getting started blog, I'm using flow-remove-types NPM package.

Install flow-remove-types package globally on your machine.

npm install -g flow-remove-types

The code sample described in the blog is launched to Index.html. Sample also has a JavaScript file with type syntax, named index.js. As described above, once we add Flow types to the code, browser can't understand Flow syntax. Hence we will generate JavaScript file without Flow types for browsers to run. In the sample I named it bundle.js. It is generated using the flow-remove-types script. Add reference to bundle.js in Index.html

Run the following command to strip types.
flow-remove-types index.js --out-file bundle.js

Refer to complete code at this link

JavaScript Idioms

Flow claims to work well with JavaScript style of coding and idioms. I attempted the following basic samples.

In the index.js to start type checking add the following comment  on top of the file.
// @flow

Consider following function

// @flow

((number1, number2) => number1 * number2)(10,20)

The function takes two parameters number1 and number2. In the above statement we are calling the function with values 10 and 20. Here flow is inferring a type number to the parameters as we are calling the function with numeric values. Consider following code erroneously providing string on the first parameter. 

// notice first parameter is a string.
((number1, number2) => number1 * number2)('Im String',20)


Flow points out the error on variable number1, string (The operand of an arithmetic operation must be a number.).



In the above example, we haven't started using types yet. Just by adding the // @flow comment on top of the file, type checking can begin and certain problems are alerted. However, the error is shown on the statement multiplying numbers for an incorrect parameter value. Flow implied string variable because the function was called with a string. It showed the error as it finds multiplication applied on string. 

Add types

Adding types makes the developer intent clear. We can declare a variable with syntax variableName: type syntax. Consider following sample

let isItCool:boolean; 
isItCool = true;

We declared a boolean and assigned true. Assigning a non boolean will show the type error.

isItCool = "test string";
string (This type is incompatible with boolean)

Now, let's rewrite the above multiplication function with types in paramters

((number1: number, number2: number) => number1 * number2)('Im String',20)

Now the error is specific, string (This type is incompatible with number)




Let us now consider specifying return type. Here I modified multiplication to addition, a string parameter will result in concatenating two values. Consider following code,

((number1, number2) => number1 + number2)('10',20)
// It will result in 1020

This depicts why explicit typing is important to avoid bugs. Consider specifying return type on the function. Following is the modified function. Notice the highlighted part for return type.

((number1, number2):number => number1 + number2)('10',20)

Specifying return type results in error depicting resultant string is incompatible with numeric type.

string (This type is incompatible with the expected return type of number

However specifying input parameters' type will point out error with string input parameter for number type in the first place.

References and more reading material

Complete Sample - https://github.com/kvkirthy/VenCKI-Samples/tree/master/Flow-basic-sample
Read getting started guide here, https://flowtype.org/docs/getting-started.html
Visual Studio Code plug-in for Flow https://marketplace.visualstudio.com/items?itemName=flowtype.flow-for-vscode