Friday, December 12, 2014

AngularJS Easiest way to upload a file

Here is the easiest way to include an upload file in your angular. This is not the angular way of doing the upload, but will get the work done. If you are doing a prototype or in a hurry, then you can use this approach.

I just have a simple view which allows user to select a file and upload it on a button click. Here is the view code.

    <div ng-controller="fileUploader">
        <input type="file" onchange="angular.element(this).scope().setFile(this)">
        <br />
        <button ng-click="UploadFile()">Upload</button>
    </div>

As you see in the above code, I defined a controller with a file input and button. On clicking the button will upload the file to the server.

Here is the angular script which sets the uploaded file to the scope and then uploads the file on the button click

'use strict';
angular.module('pos').controller('fileUploader', fileUploader)
fileUploader.$inject = ['$scope', '$http'];

function fileUploader($scope, $http) {
    $scope.setFile = function(element) {
        $scope.currentFile = element.files[0];
    }

    $scope.UploadFile = function () {
        var formData = new FormData();
        formData.append("file", $scope.currentFile);
        return $http.post("/api/user", formData, {
            headers: { 'Content-Type': undefined }, transformRequest: angular.identity
        });
    }
};


As mentioned above this is a hack solution. In my next blog I will rewrite this in an angular way by defining a directive and using it.

Monday, December 8, 2014

AngularJS Material to Replace Bootstrap

AngularJS team along with Ionic team is developing a framework that I believe is going to replace the Bootstrap and may become the defacto standard for Angular development. Right now Angular Material is in the beta stage and have few components (more is on the way). It also has a layout design much more advanced than that of the Bootstap grid system.

Please take a look at the Material Design presentation at ng-europe 2014

Also go to their demos and docs at

I just rewrote my app which was using Bootstrap to use this material design and I likeed it very much. Angular Material’s layout is much more easy to use and can do more than the Bootstrap css. It is very easy to do vertical alignment, I have to jump several hoops to do the same with Bootstrap.

Angular Material components have a good animation which improves the user experience. It also have some additional components which improve your productivity. Similar to any other frameworks, Angular Material is also designed with mobile first approach.


I strongly recommend to use this Angular Material in your angular apps. 

Tuesday, November 18, 2014

AngularJS Boolean display filter

Sometimes we may have to show a Boolean value to the user. The examples could be user is active or not. In my scenario whether a patient is premature birth or not. We typically store this information in the database or other persistence layer as a Boolean variable. When we show this property to the user, it will be shown as true or false.
Showing true or false to the user is not a very good user experience, instead of true or false we should show yes or no (or something similar) to the user. For transforming the Boolean value to more user friendly text I am using a filter in angular. As you know filter is used for format or transform the expression for the display to the user.
Here is my filter which formats or transforms the Boolean expression to display to the user
'use strict'

angular.module('pos').filter('boolText', boolText);

function boolText() {
    return function (boolValue) {
        if (boolValue === true)
            return "Yes";
        else
            return "No";
    }
}

The above filter can then be used in our bindings as below
{{vm.patientModel.PrematureBirth | boolText }}

As you see a simple reusable Boolean filter provides a user friendly display of all our Boolean variables in the module

Friday, October 31, 2014

AngularJS & Download File using WebAPI

As you know AngularJS routing overwrites the relative urls in a hyperlink so that AngularJS can handle all the requests. This sometimes causes problems. In my scenario I want to download a file when user clicks on a hyperlink in my grid. AngularJS is not sending this request to the server as a result I am unable to serve the file user wants to download.

Here is my hyperlink code that I used in the grid.

<a href="/api/download/1">Download File</a>

As you see the above hyperlink calls an webapi which in turns returns a word document that needs to be downloaded. As mentioned above clicking on this hyperlink does not download the file.
The solution for this issue is very simple, we just need to specify the target of the “a” tag as shown below

<a target="_self" href="/api/download/1">Download File</a>

Please see my other blog on how to download a file from Web API


Thursday, October 30, 2014

AngularJS UI-Router and Page title

In my previous blog, I wrote about on how to set Page title when using AngularJS routing. In this blog I will write about on how to do the same when we are using ui-router. If you haven’t read my previous blog, here is my requirement: when the user navigates from one page to another using angular routing mechanism, I want to set the page title and I would like to set this in an unobtrusive manner.

The approach and the code is almost similar in setting the page title using either with angularjs router or ui-router. But there is a minor difference due to the syntactical differences between these two routers.

Here is the code for defining the title attribute in the router

    $stateProvider
        .state("dashboard", {
            url: "/",
            title: "Dashboard",
            templateUrl: "/app/dashboard/dashboard.html",
            controller: "dashboard",
            controllerAs: "vm",
            resolve: ['dashboardService', function (dashboardService) {
                return dashboardService.resolve();
            }]
        })
        .state("login", {
            url: "/login",
            title: "Login",
            templateUrl: "/app/account/login.html",
            controller: "login",
            controllerAs: "vm",
        })
        .state("patient", {
            url: "/patient/:patientid",
            title: "Patient",
            templateUrl: "/app/patient/patient.html",
            controller: "patient",
            controllerAs: "vm",
            resolve: ['$stateParams', 'patientService', function ($stateParams, patientService) {
                return patientService.resolve($stateParams.patientid);
            }]
        })

Once the route is defined with the title attribute, I can set the window title on the state change event

        $rootScope.$on('$stateChangeSuccess', function (evt, toState, toParams, fromState, fromParams) {
            $window.document.title = toState.title;
        });

As you see we can unobtrusively set the page title by using either routers

AngularJS Routing and Page title

I came across a scenario where I would like to set the page title for each route in my angularjs app. For example if the user is in the dashboard, I want to set the page title as dashboard and when the user navigates to the patient page, I would like to set the page title as Patient. Obviously I would like to set this in an unobtrusive way.

In order to accomplish this first I defined a custom attribute called “title” in the angularjs routing as shown below:

    $routeProvider
        .when("/", {
            title: "Dashboard",
            templateUrl: "/app/dashboard/dashboard.html",
            controller: "dashboard",
            controllerAs: "vm",
        })
        .when("/login", {
            title: "Login",
            templateUrl: "/app/account/login.html",
            controller: "login",
            controllerAs: "vm",
        })
        .when("/patient/:patientid", {
            title: "Patients",
            templateUrl: "/app/patient/patient.html",
            controller: "patient",
            controllerAs: "vm",
            resolve: ['patientService', function (patientService) {
                return patientService.resolve();
            }]
        })

For each of the routes defined in my routing, I added a title attribute that will be set as a page title. After defining the title, I am setting this title on the route change event of the angularjs routing as shown below

        $rootScope.$on('$routeChangeSuccess', function () {
            $window.document.title = $route.current.title;
        });

With this approach I was able to set the title of each page at a module level (not going inside each page).

Monday, October 13, 2014

Typical AngularJS routing using ui-router

Last month I blogged about a typical routing using AngularJS router. AngularJS routing is good and works for most of the scenarios. In some situations where you need to do nested routing or some advanced routing, the current implementation fells short. It seems that the AngularJS 2.0 routing is robust and should cater to all the requirements. But that’s not going to be out soon. In the meanwhile we have an excellent routing module called ui-router. There is an excellent article on how to use this router. I provided the link to this article at the end of my blog.

ui-router supports and caters all the requirements AngularJS default routing provides. Hence I recommend to use this routing for all your scenarios. In this blog I will show my simple routing configuration using ui-router. In my subsequent blogs I will dig deeper into the nested routing and other ui-router tasks.

Here is my complete code for defining a route (for simplicity I kept only one route and removed all other routes)

'use strict';

angular.module('pos').config(routeConfig);
routeConfig.$inject = ['$stateProvider', '$urlRouterProvider', '$locationProvider'];

function routeConfig($stateProvider, $urlRouterProvider, $locationProvider) {

    $stateProvider
        .state("patient", {
            url: "/patient/:patientid",
            title: "Patient",
            templateUrl: "/app/patient/patient.html",
            controller: "patient",
            controllerAs: "vm",
            resolve: ['$stateParams', 'patientService', function ($stateParams,
                     patientService) {
                return patientService.resolve($stateParams.patientid);
            }]

    $locationProvider.html5Mode(true);

    $urlRouterProvider.when('', '/login')

}
As you see in the above code, I defined a state called “patient” and defined all the parameters for this state. Here are the salient features of this route definition
            title: "Patient",
This is not the attribute or property of the ui-router. I am using this to set the window title (which is shown in the browser toolbar). This is similar to setting the title tag. I will blog about this in my next blog.
            controllerAs: "vm",
I like the controllerAs feature. It eliminates the need of using $scope in my code and make my code clean.

            resolve: ['$stateParams', 'patientService', function ($stateParams,
                     patientService) {
                return patientService.resolve($stateParams.patientid);
            }]
This is one of the important features of my routing. I don’t want to burden my compiler with fetching the data from server and activities other than rendering. As these are model or domain specific, I create a service for each controller to handle these activities. As you know in most scenarios you need to fetch data from the server before rendering the page, “resolve” is designed for that activity. Until resolve returns (fetches the data or any other activity) Angular waits and will not render the page. Resolve option also helps avoiding the FOUC. Please see my blog on this for further details
    $locationProvider.html5Mode(true);
I am also using the html5Mode which makes my urls simple. As you know for older browsers the router automatically fallback to using “#”.
    $urlRouterProvider.when('', '/login')
Finally I am using the $urlRouterProvider to specify a default start view. In this scenario I am redirecting user to the login page.

As you see my routing with ui-router is almost similar to that of the router provided by angular. With this set, I can start using advanced routing features.

Here is a detailed blog on the using Angular ui-router Diving deep into the AngularUI Router

Sunday, September 28, 2014

AngularJS Splash Page

As you know splash page is one you show when Angular is loading. If you have too many pages in your site or depend on several heavy weight javascript libraries you page may take a while for initial loading. In those scenarios a splash page would be a good way to engage the user. A typical splash page is show a loading image to the user while AngularJS is loading.

For typical single page applications developed in Angular we use views with routing. In these scenarios it is very easy to implement the splash page. All you need is to keep your splash page inside the ng-view. When Angular loads, it replaces the ng-view with the corresponding template. Here is the html (ASP.NET MVC) code implementing the splash page.

<html ng-app="appstyleguide">
<head>
    <meta name="viewport" content="width=device-width" />
    <title>AngularJS Styleguide</title>
    @Styles.Render("~/Content/css")
</head>
<body>
    <div ng-view>
        <div id="splash" class="splash">
            Loading ...
        </div>
    </div>
    @Scripts.Render("~/scripts/libraries")
    @Scripts.Render("~/scripts/app")
</body>
</html>

In the above code, I am using ASP.NET to include the script files and css files.

In most scenarios we will be having more content than the just the ng-view directive. We will have the headers, menus etc. In those scenarios we need to hide these until Angular loads. For this Angular provides ng-cloak directive. This directive along with the css hides the content on the page till Angular loads. Here is the html with ng-cloak hiding the additional elements of the page and just showing the splash page.

<html ng-app="appstyleguide">
<head>
    <meta name="viewport" content="width=device-width" />
    <title>AngularJS Styleguide</title>
    @Styles.Render("~/Content/css")
</head>
<body>
    <div ng-cloak>
        <h2>AngularJS Styleguide</h2>
        <a href="/home">Home</a> <a href="/contact">Contact</a>
    </div>
    <div ng-view>
        <div id="splash" class="splash">
            Loading ...
        </div>
    </div>
    @Scripts.Render("~/scripts/libraries")
    @Scripts.Render("~/scripts/app")
</body>
</html>

Using ng-cloak and ng-view we can show the splash page while Angular is loading.

Please go to my GitHub project for a style guide project using Visual studio
https://github.com/prasannapattam/ng-demos/tree/master/ng-demos/ng-styleguide

Monday, September 22, 2014

Typical AngularJS routing

Here is the typical routing I use for my AngularJS apps.

$routeProvider
    .when("/app/customer/:customerid/:departmentid", {
        templateUrl: "/app/customer/customer.html",
        controller: "customer",
        controllerAs: "vm",
        caseInsensitiveMatch: true,
        resolve: ['customerService', function (customerService) {
            return customerService.resolve();
        }]

    })

As you see in addition to the regular routing attributes, I also used additional attributes such as controllerAs, resolve etc. Here is the step by step dissection of my routing configuration
    .when("/app/customer/:customerid/:departmentid", {
As all of you know, with the above statement I am defining a routing which takes customerid and departmentid as query parameters
        templateUrl: "/app/customer/customer.html",
        controller: "customer",
With these above two statements I am defining the templateUrl and controller for my routing.
        controllerAs: "vm",
I like the controllerAs feature. It eliminates the need of using $scope in my code and make my code clean.
        caseInsensitiveMatch: true,
As the name suggests, Angular performs a case insensitive matching while looking at the url for routing. This is important if are using a combination of server (like asp.net) and client routing
        resolve: ['customerService', function (customerService) {
            return customerService.resolve();
        }]
This is one of the important features of my routing. I don’t want to burden my compiler with fetching the data from server and activities other than rendering. As these are model or domain specific, I create a service for each controller to handle these activities. As you know in most scenarios you need to fetch data from the server before rendering the page, “resolve” is designed for that activity. Until resolve returns (fetches the data or any other activity) Angular waits and will not render the page. Resolve option also helps avoiding the FOUC. Please see my blog on this for further details

As you see with my routing configuration, I am able to handle the preprocessing and also reduce the dependency of global $scope variable. 

Tuesday, September 2, 2014

Book review of Kendo UI Cookbook

Last week I did a review of the Kendo UI Cookbook and here are my review comments:



Urlhttps://www.packtpub.com/web-development/kendo-ui-cookbook

Rating: 4 / 5

Review comments:

If you go over to the Kendo UI site, you can see their awesome demos. But if you want to implement those controls in your project, then there is little help on the Kendo site. They just dump the code with no explanation and you need to be an expert to understand their documentation. There is a huge gap on the Kendo site. This book nicely address that gap. Actually you get more benefit if you use this book in tandem with KendoUI.com. In addition this book goes beyond the typical demos on the Kendo site and provides much more information. It alerts the common gotchas and goes in depth. I believe that the goal of this book is to provide easy to use recipes for complex controls. If this is correct then it did a good justification. 
The good:
  • This book provides wealthy of details for each receipe with its "How to do it" and "How it works" sections
  • This book even goes one step ahead and provides advance use of the controls with the "There's more" section. Some of these tips are not found on the Kendo site
  • This book is a must read if you are building mobile web applications.

  
Nice to Have:
  • I would have liked this book more if they used the same demos as on the Kendo site. This helps reader to get a feel of the controls while reading the recipes.
  • As AngularJS is gaining popularity, this book should have provide some recipes using Kendo's angular directives

 The bad:
  • In my opinion this book fell short of covering the most widely used KendoUI form controls such as DatePickers, textboxes etc.
  • This book starts with the complex framework chapter which may scare beginners. If you a beginner, just skip the first chapter
  • Sometimes I feel that this book is not properly organized. It does not provide me a story. I believe this is due to the book's goal to cover the complex controls

 Bottom line:
  • If you are a UI developer or designer who wants to build web sites with awesome Kendo controls then this book is for you.
  • If you are a backend developer and looking to use Kendo form controls then look elsewhere.