AngularJS in 19 Days : Download the free eBook with samples

Hello All,

As you might be following the series of posts on AngularJS from last couple of months and that I completed 20 post and covered range of topics. Based on many suggestions, I have updated all those posts with current version 1.4, since initial posts were using other using 1.0+, added navigation links etc. Now I have incorporated compiled all the posts, refined the content and sample a bit and happy to present it in a format of eBook. I am sure it will be very handy and easy to read and follow till end.

About the ebook :

ebookcoverFor those who were not following the series of post, As the name suggests this book in divided in 19 days from Introduction to covering most of the core topics including unit tests. The sample of each day can be downloaded from GitHub. This is not just another e book which covers the basics of AngularJS or cover everything, but it is a unique combination of basics and details description of core concepts with sample. If you are ASP.NET MVC developer then it will become more fruitful to you as some of days it covers that how and what are best ways to use Angular in ASP.NET MVC project. I am sure you will enjoy the book and will share your feedback that will help in upcoming new version.

 

Download the book from here

Thanks
Brij

Advertisement

User Name availability check with AngularJS, ASP.NET MVC and ASP.NET Web API


User Name availability check is required in most of the registration forms where we allow user to choose a user name that one can use to login later. In some other scenarios, we allow user to use his/her email as login id/user name. In both the scenarios, we require to make sure that user name or email is not used earlier. In this post, I am going to discuss, how to achieve this feature in an application which is developed using AngularJS, ASP.NET MVC and ASP.NET Web API. I wont discuss in detail the Data Access part, where one can use any approach like Entity Framework, Identity Framework , Membership provider or ADO.NET.

In this post, we will create an empty ASP.NET project with MVC and Web API. We’ll start working on Web API  part where an API will be exposed which will take user’s entry for user name as input and return true and false based on its existence. After that we will work on MVC part where we will create a registration form where user will put its information. In last, we will focus on AngularJS and create the basic infrastructure including a Service which will call the Web API to check the user name existence then how will do the check on view we will discuss at later section.

I created an API folder under Controller and created an empty Web API controller (RegistrationController) which exposed an API IsUserNameAvailable which takes an username and returns true if available else returns false. It is as

  [RoutePrefix("api/Register")]
    public class RegistrationController : ApiController
    {
        [Route("IsUserNameAvailable")]
        [HttpGet]
        public bool IsUserNameAvailable(string userName)
        {
            IRepository rep = new SQLRepository();
            IList<UserAccount> users = rep.GetUser(userName);
            return users.Count == 0;
        }
    }

 

Inside the API, I have used a SQLRepository which connects to the database and returns a list of users based on it. If there is no match then list contains no items. Let’s have a look that our table in database form where the account is getting matched.

table

Now let’s just quickly check that whether our API is working properly. The simplest way to check any API Get request via browsing the URL itself. So let’s check the URL

http://localhost:4077/api/Register/IsUserNameAvailable?userName=Brij

So as we see that Brij exists in the database so it returns false.

WebAPIResult

Now let’s create an empty MVC controller (UserRegistrationController) and View for the Index action which has an input control to enter the username.

Now its time to introduce the AngularJS into the application. Let’s see that what all the AngularJS components we need to create to implement the feature.

  1. Angular Module – To bootstrap the application.
  2. Service – This service will connect to exposed Web API to check the user name availability. It will initiate the AJAX (http) call and get the appropriate response accordingly.
  3. Angular Controller- To add some logic
  4. Custom Directive – We will discuss it in later section

I have created a new folder Registration in scripts folder to put all the angular resources. I created an angular module (file name as RegModule) which has currently

var registrationModule = angular.module('registrationModule', []);

Now it time create a service which will connect to the server to check the user availability and return true or false accordingly. I am using Factory method for creating service as

registrationModule.factory("RegService", function ($http, $q) {
    return {
        IsUserNameAvailablle: function (userName) {
            // Get the deferred object
            var deferred = $q.defer();
            // Initiates the AJAX call
            $http({ method: 'GET', url: 'api/Register/IsUserNameAvailable?userName=' + userName }).success(deferred.resolve).error(deferred.reject);
            // Returns the promise - Contains result once request completes
            return deferred.promise;
        }
    }
});

Now to handle the UI part, we have two options

1- Either we do all the UI manipulation using Angular controller and add the required code. Or

2- We can create an custom directive where all the logic will be put to check the uniqueness of the username and updating the UI.

Lets quickly see first option, where we will write the logic in Angular Controller  as

    $scope.checkUserAvailable = function () {
        RegService.IsUserNameAvailablle($scope.Registation.username).then(function (userstatus) {
            $scope.registrationForm.username.$setValidity('unique', userstatus);
        }, function () {
            alert('error while checking user from server');
        });
    };

Here we are using $setValidity of for the model and add the unique attribute and set it true/false based on the service response. This will set the validity of the input as true/false and we can show some messages based on that. So let’s see the form


<div class="container" ng-app="registrationModule">

<div class="row" ng-controller="regController">

<form name="registrationForm" role="form">
            <label for="username">User Name:</label>

<div class="form-group">
                <input type="text" name="username" id="username" ng-model="Registation.username" class="form-control" placeholder="Username" ng-blur="checkUserAvailable()" />
                <span class="alert alert-danger" ng-show="registrationForm.username.$dirty && registrationForm.username.$error.unique">
                    User name is not available
                </span>
            </div>

        </form>

    </div>

</div>

We are calling checkUserAvailable function in blur event so that it gets fired when user moves focus from the control after entering the data. We also added a span (p) to show the error message which checks the input control state and unique attribute that we added. Now let’s run the application and see

sample

As Brij is already exists in the database so it is not available and if you enter any other username which is not available in database, it wont show the message.

Second option is much cleaner so we will create a custom directive (I have written 19 posts on AngularJS, you can go here to learn all the topics or for custom directives refer the Part -9 and Part -10)

So let’s create our custom directive. Here it will use the RegService and add an onblur event to the input which will be fired once user goes out of the control after entering the some data as

registrationModule.directive('useravail', ['RegService', function (RegService) {
    var directive = {
        restrict: 'A',
        require: 'ngModel',
        link: function (scope, element, attrs, ngModel) {
            element.on('blur', function (evt) {
         
                if (!ngModel || !element.val()) return;
                var curValue = element.val();

                RegService.IsUserNameAvailablle(curValue)
                .then(function (response) {
                        ngModel.$setValidity('unique', response);
                }, function () {
                    //If there is an error while executing AJAX
                    ngModel.$setValidity('unique', true);
                });
            });
        }
    }
    return directive;
}]);

Here we have used similar code that we wrote in angular controller. Here we added blur event to the input control in directive. So let’s see the form


<div class="container" ng-app="registrationModule">

<div class="row">

<form name="registrationForm" role="form">
            <label for="username">User Name:</label>

<div class="form-group">
                <input type="text" name="username" id="username" ng-model="Registation.username" class="form-control" placeholder="Username" useravail />
               // later code is same as first option so removed forbrevity

We have set the ng-model and added our custom directive useravail as an attribute at the end in the input element. When we will run this application, it will have same as first option.
So we have implemented User name check using AngularJS, ASP.NET MVC and Web API. We can change the look n feel based on our need. Complete code is attached with this post.

Cheers
Brij

ASP.NET MVC and Angular Routing together – Part 11

[To view earlier posts of the series – Click Here]
This will be short but very helpful post. I have seen lots of questions and confusion over Angular Routing and ASP.NET MVC Routing. In this post, I will try to unravel. We all already know the following two points

1- ASP.NET MVC is a server side technology so it means ASP.NET MVC routing takes place at Server.

2- AngularJS is a client side technology so Angular routing itself cannot conflict with ASP.NET MVC in any way. But it works on the top of the ASP.NET MVC. Let’s discuss it with a example.

I will be taking the sample from one of my earlier posts (Learning {{AngularJS}} with ASP.NET MVC – Part 5) on AngularJS and modify a bit for this post. Let me brief about the\example

1- It has one MVC controller – named EventsController that has three methods. One returns the index view and in rest of the two, one returns a list of talks and other, list of speakers in JSON format.

2- It has two angular routes, one for listing speakers (/Events/Speakers) and another from listing talks (/Events/Talks). These urls are used in top menu. So when we run the application and the url (http://localhost:/ or http://localhost:/events or http://localhost:/events/index) the page loads as homeAfter clicking the the two tabs talks or speakers are loaded accordingly. Angular Routes in the sample are defined as

var eventModule = angular.module("eventModule", []).config(function ($routeProvider, $locationProvider) {
 //Path - it should be same as href link
 $routeProvider.when('/Events/Talks', { templateUrl: '/Templates/Talk.html', controller: 'eventController' });
 $routeProvider.when('/Events/Speakers', { templateUrl: '/Templates/Speaker.html', controller: 'speakerController' });
 $locationProvider.html5Mode(true);
 });

Now if we access the direct angular defined routes (like ) it does not work. Let’s understand why?

When we access the url http://localhost:48551/events/index then it actually calls the MVC EventsController and Index action as expected and loads the page. Now when we click on one of the tabs (say speaker) then Angular chips in and it loads the angular view. The call does not go to MVC controller and action at server rather it gets handled at client side by Angular. It loads the data via angular service that initiates the ajax call to server to get the data. Here the url changes but handled at client side only and server (or say ASP.NET MVC) does not even get to know about it.

Now the next question, in second case, why the call does not go at server? In first case, there is nothing available at client side and request goes to the server and gets the page. When page loads it loads everything including angular library. Now when second time, the url gets changed Angular checks whether it can handle the url if yes then it just process it at client side and if not then try to load otherwise url if defined else loads nothing and leave it empty. The whole process can be defined it pictorially

ngrouteupdatedNow we can imagine a scenario while accessing a Angular defined url (http://localhost:48551/Events/Talks) as initial request, it finds nothing at client side which can handle it as it is a fresh request. And it goes to server and tries to find the EventsController and Talks action but it is not defined by ASP.NET MVC so it does not work. We just have Index action at MVC controller. Now how to resolve this issue?

As Initially in this post, I pointed out that Angular defined urls are handled at Client side only, so AngularJS must be loaded and initialized before it can handle the request. There would be two steps involved

1- All angular defined urls should be mapped to a MVC route that returns the response to client with all the client side libraries including Angular.

2- Then as angular is initialized, it handles the url as discussed earlier When we try to access an angular defined urls as first request, it goes to server then we need to initialize the page first with AngularJS then rest angular takes care.It means that in the example, we need to call the index action when somebody try to access the AngularJS urls (Talks and Speakers) directly which will load the page and it will initialize the Angular as well then the Angular urls will be handled by angular itself. So how to do that, we just need to add some routes in Global.asax of so that even if Angular defined urls are called it returns fires of the index action only. So we can add it like

 public static void RegisterRoutes(RouteCollection routes)
 {
 routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

 routes.MapRoute(
 name: "EventsCourses",
 url: "Events/Talks",
 defaults: new { controller = "Events", action = "Index", id = UrlParameter.Optional }
 );
 routes.MapRoute(
 name: "EventsSpeakers",
 url: "Events/Speakers",
 defaults: new { controller = "Events", action = "Index", id = UrlParameter.Optional }
 );

 routes.MapRoute(
 name: "Default",
 url: "{controller}/{action}/{id}",
 defaults: new { controller = "Events", action = "Index", id = UrlParameter.Optional }
 );
 }

So here I added two routes EventsCourses and EventsSpeakers for Angular Urls and for both, index action of events controller gets called.

Here we should not have a URL which can be processed by Angular and MVC both in that case you will get different behavior in both the case so we should keep in mind while defining the URLs. So I hope it must have been clear to you. Also you do not need to add each AngularURL as new route in Global.asax, you can have unique pattern in Angular URLs and for that pattern, you can have just one route which return the same action for that pattern. Sample is attached with the post.

[Update : Updated the flow diagram of this post and content to add some clarification in a scenario when requested url is not defined in URL – 04th May 15]
To navigate to previous and next post of the series, use the links at the bottom of the post.

Happy Learning
Brij

DataBinding in {{AngularJS}} – Part 7


This is the seventh post in the series of AngularJS and today, we will discuss one of the features that we already used – Data Binding in details. For earlier posts of the series, please refer the links below

Learning {{AngularJS}} with Examples–Part 1

Learning {{AngularJS}} with Examples–Part 2

Learning {{AngularJS}} with ASP.NET MVC – Part 3

Learning {{AngularJS}} with ASP.NET MVC – Part 4

Learning {{AngularJS}} with ASP.NET MVC – Part 5

Learning {{AngularJS}} with ASP.NET MVC – Part 6

Let’s just take a quick look on our picture trackerpicture-tracker

Broadly, Data binding can be divided in the two parts
– One way binding
– Two way binding

Continue reading

Learning {{AngularJS}} with ASP.NET MVC – Part 6

It’s been around a month since I wrote the fifth part of the series on AngularJS. We have covered a bunch of concepts in our last five posts. I will advise to go first the earlier posts then continue reading it. Links of my earlier posts on this series are.

Learning {{AngularJS}} with Examples–Part 1

Learning {{AngularJS}} with Examples–Part 2

Learning {{AngularJS}} with ASP.NET MVC – Part 3

Learning {{AngularJS}} with ASP.NET MVC – Part 4

Learning {{AngularJS}} with ASP.NET MVC – Part 5

In our last post, we created a sample where we had a page that comprised two views : Talk details and Speaker Details. We fetched two sets of data (Talks and Speakers) from server via  AJAX call and rendered on the page using templates with the help of Angular rendering engine. In this application, we are going to use again the same application and add some more features which are relevant in our day to day coding.

In today’s post, we will use almost the same concepts that we discussed in our last post but use it for different scenario. Let’s put our picture tracker.

trackerHere I highlighted four components and we had already used it one or other ways in earlier posts. But we’ll discuss the new highlighted components briefly here as well.

Continue reading

Learning {{AngularJS}} with ASP.NET MVC – Part 4


This is fourth part in the series on AngularJS and till now we have discussed some basic components and used those in our examples.The links of my earlier post on this series are

Learning {{AngularJS}} with Examples–Part 1

Learning {{AngularJS}} with Examples–Part 2

Learning {{AngularJS}} with ASP.NET MVC – Part 3

So what will we be covering today. Let’s see our picture tracker

image

In our earlier posts in the series, we discussed five components. As we see in the above image, in this post, we will discuss services again. Angular services is vast topic but I am discussing the important concepts. One of the important technology that we use in a web applications is AJAX. So in today’s post our focus would that how AngularJS enables us to use AJAX.

Continue reading

Html.EditorFor – Extend for custom type

In this Post, I am going to discuss about ASP.NET MVC and razor view engine. As we know that ASP.NET MVC provides many helper methods that helps in generating the UI based on the model. But there could be scenario where the available HTML helpers wont work and you require to create new custom one. There could be one scenario, where you have a class that has a enum property. Now if you create a Create/Edit view for that property then it will just create a TextBox for it. Obviously which is not a good idea. A User may enter some wrong string which cannot mapped to a enum value. So the better way to provide a dropdown to select any value. There could be many ways to render it. We’ll discuss one elegant way to do this.

First let’s understand that how does the available helpers work. Lets start with an example. Say we have a class like

    public class Speaker
    {
        public int Id { get; set; }

        public string Name { get; set; }

        public bool IsAvailable { get; set; }
    }

So here, in this class there are three properties: Id, Name and IsAvaiable. The first two are of type string and third one is of bool. So when we create a View for this model It looks like

</pre>
<div class="editor-field">@Html.EditorFor(model => model.Name)
 @Html.ValidationMessageFor(model => model.Name)</div>
<div class="editor-field">@Html.EditorFor(model => model.IsAvailable)
 @Html.ValidationMessageFor(model => model.IsAvailable)</div>
<pre>

I have not included the whole source code of the View but if we see the above code then find an EditorFor (called templated helper) is used to generate the UI. Let’s run and see the UI Initial We can see one Textbox and other Checkbox on the screen right. But how does it take place? Actually when it renders on the browser, it checks the type of the property, and based on the type, picks the appropriate template and renders it on screen. For type string(which is name here), it has a defined template as Textbox and for bool (which is here IsAvailable) also it has a template as Checkbox . So the same templated editor method renders different UI based on the type of the property. Let’s move ahead and add another enum property I have created a enum type as

 public enum ExpertiseArea
    {
        ASPNET,
        Csharp,
        WindowsAzure,
        WCF
    }

Now lets add one more property to the class of type enum defined as above

public ExpertiseArea Area { get; set; }

Now we need to add a new editor for Area as

</pre>
<div class="editor-field">@Html.EditorFor(model => model.Area)
 @Html.ValidationMessageFor(model => model.Area)</div>
<pre>

When it will be rendered on UI, it will simply add a Textbox for enum as

withoutddl

which is not a good Idea as discussed. To provide a Dropdownlist for the enum, we need to create a custom editor template.

To create a custom editor template, create a folder named EditorTemplates under Views->Shared folder. So that the editor templates gets available to all the Views.Now create a Partial View under that folder with name as your Enum (which is here ExpertiseArea so partial view file name will be ExpertiseArea.cshtml). Now in this View we need to create the drop down list. For dropdown list, we need to get all the item names from the Enum Type and create the items for drop down. So here my my partial view ExpertiseArea.cshtml contains

@using System.Web.Mvc;
@using Application1.Models;
@{
    var names = Enum.GetNames(typeof(ExpertiseArea));
    var values = Enum.GetValues(typeof(ExpertiseArea)).Cast();

    var items = names.Zip(values, (name, value) =>
        new SelectListItem { Text = name, Value = value.ToString() });
}

@Html.DropDownList("", items)

In above code, We are getting all the names and values from Enum and creating the items for dropdown and once we create the items, we used the dropdown list helper to populate the dropdown. So now lets render the create the page again.

dropdownNow a dropdown is rendered with all the possible enum type values for enum type property. And the same will be used at many places, wherever we want to get the user input on this enum value. And there will be no change in the Views.

So we have seen that how easily we can create custom editors for specifc types and can use it uni formally in the entire application.

Happy Learning,
Brij

Working with WebGrid using AJAX : ASP.NET MVC

I am going to write another post on ASP.NET MVC. Here in this post, I’ll be talking about WebGrid. If you have read my last post ( to go Click here), I had a main View and many Partial Views that are integrated with main View. Every partial view was independent and we loaded each partial view via jQuery AJAX call.

I got another requirement to have one more partial view on that page which also shows the data similar to other controls but here the requirement was to provide a specific feature Sorting. So as I was looking for various options for it. First I thought to making my custom partial view which provides the desired behavior. But I thought of using any existing control.

Continue reading

Loading the partial views using Ajax for Beginners

Last week, I was working on an application that was made in ASP.NET MVC3. Earlier I thought of using ASP.NET MVC 4 but didn’t find any specific feature of ASP.NET MVC4 so moved ahead with ASP.NET MVC3 version.

So as I worked on a POC using with ASP.NET MVC initial version long back so I was excited working on it. I had to display multiple user controls and the data of these controls was getting picked up from multiple sources. So I thought of loading the controls via ajax call individually. So let me share my understanding with a example. I have created a sample application in ASP.NET MVC3. I created a main View (called here HomePage.cshtml)and created two Partial Views (_ProductDetails.cstml and _UserDetails.cshtml) that will be displayed. So I’ll show you how easily we can load these controls via Ajax. It will make page more intuitive and seamless to users.

Continue reading