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.

In this post, we’ll be discussing that How can we post the data to server or to MVC Action. We will use the same application and add another view which will allow us to create a new talk and post to the server.

So before jumping into the code, let’s first see what all we need to complete it.

1- Create new template for Add Talk.

2- Create a controller (say talkController.js) for the Add Talk view.

3- Add an ajax method in EventsService to post the data on server (Calls a MVC action method)

4- Create a new Action method say AddTalk in EventsController.cs at server side.

5- Wire out the controller with module.

6- Handle the ajax response accordingly

Creating New template

So let’s start with first step. I have created the talk template (AddTalk.html) based on earlier model and it is as

<table>
    <tr>
        <td>Id</td>
        <td><input type="text" ng-model="talk.Id" class="form-control" /></td>
    </tr>
    <tr>
        <td>Name</td>
        <td><input type="text" ng-model="talk.Name" class="form-control" /></td>
    </tr>
    <tr>
        <td>Speaker</td>
        <td><input type="text" ng-model="talk.Speaker" class="form-control" /></td>
    </tr>
    <tr>
        <td>Venue</td>
        <td><input type="text" ng-model="talk.Venue" class="form-control" /></td>
    </tr>
    <tr>
        <td>Duration</td>
        <td><input type="text" ng-model="talk.Duration" class="form-control" /></td>
    </tr>
    <tr>
        <td colspan="2" align="center"> <input type="button" ng-click="add(talk)" value="Add New Talk"/></td>
    </tr>
</table>

I have put the above file in the template folder as earlier. Let’s discuss about ViewModel.

ViewModel – In my last couple of posts on AngularJS, we used $scope various times and discussed it in brief that it acts as a glue between views and controllers. Let’s describe it bit more

$scope is kind of dynamic object which acts as an application model and it is accessible to views and controller. All the data/expression/code sharing is done via $scope between view and controller. It provides some more features like watch and apply APIs that we’ll discuss in coming posts.

On every input control, I have added an ng-model attribute, and provided the model name.Let’s discuss what is ng-model.

ng-model – It is a directive that is used to bind the input (select and textarea as well) control to a property that on the current scope. If it finds the property already available then it uses the same else creates a new one dynamically. Binding with model is handled using NgModelController. It provides many other feature like validation, other various states of the data etc that we’ll be discussing in coming post.

Note : If you are adding the new properties and want to serialize it at at server with server side model, make sure the property names used in the model, should match with server side model else it will not be populated.

Above template also contains a button control that has ng-click attribute. This allows us put the function/expression  that would be evaluated on button click. So here we have a provided a add method which takes talk as parameter. Now let’s move to our angular controller.

Creating an angular controller – In our earlier controllers, we added a method that gets fired on load and which further gets the data from server using a service and assign it to $scope. But here, we have different scenario, here we have a call a method on the button click that further sends the data to server with the help of other various components.

So our controller could be written as (I have created a new JavaScript file named talkController.js)

eventModule.controller("talkController", function ($scope, EventsService) {
    $scope.add = function (talk) {
        EventsService.addTalk(talk);
    };
});

So here we added a new property add to $scope which points to the method that handles Add Talk functionality. As $scope is available to the view so it can be accessed via ng-click directive. If we see the controller then we find that we call a method addTalk of the EventsService that takes an input parameter talk as well. So let’s add this new method to EventsService.

Adding method to Service - Here we will add a new method addTalk that will initiate an ajax request and post the data at server. So let’s see the code

 addTalk: function (talk) {
            // Initiates the AJAX call to the server
            $http({ method: 'POST', url:'/events/AddTalk', data: talk });
        }

Here we are just initiating an ajax call and posting data (talk) AddTalk method on server.

Adding MVC Action method to the server – From the above ajax call, we can see that it calls a method AddTalk at the server. Let’s add it in EventsController.cs accordingly

[HttpPost]
public ActionResult AddTalk(TalkVM talk)
   {
        eventsRepository.AddTalk(talk);
        return new HttpStatusCodeResult(HttpStatusCode.OK, "Item added");
   }

Here we added an Action AddTalk and added HttpPost attribute on top of that so that it can be called via Post method only.

Registering angular Controller with Module

As we have created a controller, now we need to register with the module. We know that Module is like a container and every component need to be registered with it. It looks like

 $routeProvider.when('/Events/AddTalk', { templateUrl: '/Templates/AddTalk.html', controller: 'talkController' });

The code here is very similar to our last posts. We just provided here the route, templateUrl and corresponding controller.

Now let’s add the link for AddTalk at our MVC view as

 <li class="navbar-brand"><a href="/Events/AddTalk">Add Talk</a></li>

Here I added an li with the link of Add Talk that points to the route that we defined for Add Talk in the module. Now we are done. Let’s run our application

AddTalkSo when I clicked on Add New Talk, it successfully posted on the server. But it remained on the page without any message. Normally, if it gets successfully added then it should move to listing page and in case of failure, it should display a user friendly message.It can be achieved easily if we modify our code a bit. From our MVC Action, we are already sending a HTTP response code to the client. We just need to capture it and act accordingly.

So let’s change ourangular service as

        addTalk: function (talk) {
            // Get the deferred object
            var deferred = $q.defer();
            // Initiates the AJAX call
            $http({ method: 'POST', url:'/events/AddTalk', data: talk }).success(deferred.resolve).error(deferred.reject);
            // Returns the promise - Contains result once request completes
            return deferred.promise;
        }

Here we are returning the promise object as used in earlier posts. Now we need to handle it accordingly in our controller. So let’s see the updated controller

eventModule.controller("talkController", function ($scope, $location, EventsService) {
    $scope.add = function (talk) {
        EventsService.addTalk(talk).then(function () { $location.url('/Events/Talks'); }, function ()
        { alert('error while adding talk at server') });
    };
});

Here I have used one more inbuilt angular service called location service. Let’s see what it is

$location – $location service is another angular inbuilt services, that parses the url in the browser and make it available for use. It provides mainly two features : change the url in the browser or do something when the url changes in the browser. WE can also understand similar like Window.location.

So here we are loading the talk details in case of success and showing an alert message in case of failure.

Now when we click on Add New Talk on add talk form, it redirect to talk details as

added

So here we can see the talk got added successfully. Sample is attached with the post.

Thanks,
Brij

Presented on AngularJS at C# Corner Delhi chapter event – 28th June

Hello All,

C# Corner again organized a fantastic full day event on 28th June where attendees got a chance to learn hot technologies and chance to hear big names like like Mr Mahesh Chand and Mr Pinal Dave. In this full day event, I presented one of the most discussed technologies, AngularJS. It was an awesome session which was full of knowledge, demos and humor. I covered the following points

  • Intro to AngularJS
  • First Angular Application
    • Controller
    • $scope
    • Expression
  • Flow of an Angular App
  • Another Demo
    • DataBinding
    • ng-repeat
    • Filter
    • Modules, Views and Controllers (All in one)

Please find below the link to download demo and presentation .

For official recap of the event click here

Happy learning,
Brij

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

This is the fifth part in the series of AngularJS. We have discussed the basic components of AngularJS in our earlier posts. Please find the links of my earlier post on this series as

 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

So let’s move to series tracker and see what are we going to learn today.

structuctureSo far, we have discussed five main components. Today we will be discussing Views and Routing.

Earlier whenever we required to display multiple views on a single webpage then we normally put multiple divs on the page and show or hide div using JavaScript or jQuery. One of the main issues with this approach is that the URL does not change as view changes so bookmarking any particular view is not possible. It also becomes tough to maintain these pages as it contains lots of html and javaScript code as well.

AngularJS provides a robust solution to handle these scenario. First it enables us to help in maintaining multiple views of the page in separate files, that will be used to load the particular view. It also allows us to have different URL based on view. Let’s understand Views and Routing.

Views – To have different views on the page, we have different templates which gets rendered on in ng-view directive based on the routes.

Routing – Routing plays a key role of having multiple views on the same page. It enables us to provide different templates(View) and controller based on URL. On clicking particular url, the corresponding template is loaded based on the assigned controller. Routing is supported by another angular service called $routeprovider

Note –  These Views are similar to ASP.NET MVC views. These views require data that can be passed using controller and it renders itself based on it.

So let’s discuss the example. We’ll take the last post’s sample and scale it up. In that example, we displayed Talk details on the page. Now we will display speaker details on that page as well. So we’ll have two tabs: Talk Details and Speaker Details. And by clicking on the tabs, corresponding details will be displayed.

So let’s write the server side code first

1- Added a new method GetSpeakers in EventRepository that returns an array of speakers. The code is as

        public SpeakerVM[] GetSpeakers()
        {
            var speakers = new[]
            {
                new SpeakerVM { Id= "S001", Name= "Brij Bhushan Mishra", Expertise= "Client Script, ASP.NET", TalksDelivered= 28 },
                new SpeakerVM { Id= "S002", Name= "Dhananjay Kumar", Expertise= "Node.js, WCF", TalksDelivered= 54 },
                new SpeakerVM { Id= "S003", Name= "Gaurav", Expertise= "Microsoft Azure", TalksDelivered= 68 }
            };
            return speakers;
        }

2- Added a new method in GetSpeakerDetails (similar to GetTalkDetails) in EventsController that gets the data from Repository and returns the JSONResult. This method will be called via Angular Service. The method is as

        public ActionResult GetSpeakerDetails()
        {
            var settings = new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() };

            var jsonResult = new ContentResult
            {
                Content = JsonConvert.SerializeObject(eventsRepository.GetSpeakers(), settings),
                ContentType = "application/json"
            };

            return jsonResult;
        }

Now we have added server side code. Let’s move client side coding

1- Added a new service getSpeakers in Event Service as

        getSpeakers: function () {
            // Get the deferred object
            var deferred = $q.defer();
            // Initiates the AJAX call
            $http({ method: 'GET', url: '/events/GetSpeakerDetails' }).success(deferred.resolve).error(deferred.reject);
            // Returns the promise - Contains result once request completes
            return deferred.promise;
        }

It is similar to getTalks that we discussed in my last post.

2- As every view has one controller so let’s create another controller for speaker details named as speakerController (speakerController.js) and put the code similar to eventController as

eventModule.controller("speakerController", function ($scope, EventsService) {
    EventsService.getSpeakers().then(function (speakers) { $scope.speakers = speakers }, function ()
    { alert('error while fetching speakers from server') })
});

3- Now it’s time to create to templates that will be rendered on the UI. For that, I have created Templates folder. In this folder we’ll create templates for talk and speaker. So let’s create an HTML file named as Talk.html and copy the html from Index,html and it looks like as

<div class="container">
    <h2>Talk Details</h2>
    <div class="row">
        <table class="table table-condensed table-hover">
            <tr>
                <th>Id</th>
                <th>Name</th>
                <th>Speaker</th>
                <th>Venue</th>
                <th>Duration</th>
            </tr>
            <tr ng-repeat="talk in talks">
                <td> {{talk.id}}</td>
                <td> {{talk.name}}</td>
                <td> {{talk.speaker}}</td>
                <td> {{talk.venue}}</td>
                <td> {{talk.duration}}</td>
            </tr>
        </table>
    </div>
</div>

Let’s create similar view for Speaker View as well, It is as

<div class="container">
    <h2>Speaker Details</h2>
    <div class="row">
        <table class="table table-condensed table-hover">
            <tr>
                <th>Id</th>
                <th>Name</th>
                <th>Expertise</th>
                <th>Talks Delivered</th>
            </tr>
            <tr ng-repeat="speaker in speakers">
                <td> {{speaker.id}}</td>
                <td> {{speaker.name}}</td>
                <td> {{speaker.expertise}}</td>
                <td> {{speaker.talksDelivered}}</td>
            </tr>
        </table>
    </div>
</div>

4- Let’s go to index.cshtml. Now in this file we’ll have only tabs and one more new item ng-view as

<div class="container">
    <div class="navbar navbar-default">
        <div class="navbar-header">
            <ul class="nav navbar-nav">
                <li class="navbar-brand"><a href="/Events/Talks">Talks</a></li>
                <li class="navbar-brand"><a href="/Events/Speakers">Speakers</a></li>
            </ul>

        </div>
    </div>
    <div ng-view>

    </div>
</div>

Here I have used navbar to create the navigation links. Please refer the href links, one is for Talks and another for Speakers.

As discussed, inside ng-view the required templates will be rendered.

5- Now we have only one item that is left, to initialize the route that is defined in the module 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);
});

As we earlier discussed that module is like container to all the features and services. Route is configured via config method in module. Path of the link should be same as the path used in the navigation links.
Now our application is ready and let’s run this.

UntitledHere I ran the application and clicked on the Talks link (red encircled). After the url got changed(refer url) and talks got populated. similarly let’s click on Speakers

speakersWhen I clicked the speaker the url also got changed which enables us to bookmark the url based on the view. The sample is attached.

Hope you have enjoyed this post.

Cheers,
Brij

Got awarded Microsoft MVP fourth time in a row

Hello All,

imagesI am very happy to inform you all that I have been awarded Microsoft Most Valuable Award fourth times in a row. First time, I got this award on 1st July 2011 and getting it consecutively since then. It is really a great honor and matter of pride to me. I received this award ASP.NET/IIS category since beginning.

This award is never been possible without all of you. I would like to thank each one of you for your support and feedback. I will try to spend more time in community and sharing knowledge on various technologies.

I would like to name Mr Mahesh Chand and C# Corner. C# Corner is a fantastic platform for IT professionals which help in learning and career growth.

I would also like to name some of the legends Pinal Dave, Gaurav Mantri, Shiv Prasad Koirala and many more who always motivates  me. Some of my friends Dhananjay Kumar, Abhijit Jana, Amit Chaudhary, Abhishek Sur, Kunal Choudhary, Lokesh Vij, Sri, Sudeep.. and there is a long list, they all always lent me their support whenever I required. I’ve also learnt a lot from many blog friends Daniel, Pete O Hanlon, Alan Beasley, Petr Pechovic, Sacha and many others.

How can I forgot to mention, my parents and my wife Renu who always support me and bear with me in tough times

At last, I would say that I’ll keep participating and devoting my time to community with the same intensity and share my knowledge and learn from all of you. Your feedback is utmost important for me that I’ll seek every time.

Cheers,
Brij

Leverage output caching with IIS7.X and IIS8.X

Caching is one of key items that is being discussed whenever we talk about the performance of a web application. We always to use caching as a primary tool while designing and development of a web application. ASP.NET itself supports different kind of caching for handling various scenarios. Although we talk about it a lot, but I have seen that it is not implemented properly at most of the applications

I’ll not talk about it in detail about Caching in this post. Although I wrote an article on this topic in detail on www.codeproject.com long back, you can refer it for getting more information

State management and ways to handle Cache in a Web Farm/Web Garden scenario

Note : As this post was written long back (Apr 2011) some of part of could be old and may not be relevant in the current scenarios.

Let’s comeback to the topic. There are different ways to implement caching and one of the caching technique is called Output caching. But let’s understand that what is output caching?

Output caching is a way to cache a specific page or some part of the page and whenever a request comes for that specific page, if that is available in output cache, it gets delivered from there.

IIS 7.X and 8.X provides us capability to enable output cache based on certain criteria. In normal scenario, when a page request comes to IIS, it goes first with IIS Pipeline and then further goes though ASP.NET Pipeline before the request gets served. So if we cache some items at IIS itself, then we can save the whole IIS pipeline and ASP.NET pipeline. So let’s see how to enable that.

Enable output caching at IIS

Step -1 :  Go to IIS manager. (Type ‘inetmgr’ at run and press ok)

run

Step – 2: Select your website (where you want to enable caching) under Sites

selecsiteStep -3: Go to Features View and click on Output Caching under IIS category.

iisoutput

Step – 4 : Select Add… from right hand pane and it will open the below window

CacheRule

`We need to provide the extension of the file name that we want to cache and select other options.

Here, IIS provides two options to enable caching.

1- Kernel-mode level

2- User-mode caching.

So before making any choices, let’s have a look IIS architecture at Higher level .

IISWhat is HTTP.sys here?

HTTP.sys is kernel mode device driver which act as HTTP Listener which listens HTTP and HTTPs requests directly from the network and then pass it to user mode for further processing.

If we cache something at kernel mode then it will be very fast as it picks the request direct from the network and return from here only if it is cached. It will even save the whole IIS and ASP.NET pipeline.

It provides some options while enabling it

1- File Change notifications

2- Provide time interval – Based on the provided time interval cache will be invalidated.

3- No cache

As the features of IIS is not available at kernel-mode so there is some limitation with kernel mode caching like if request needs to be authenticated then caching at kernel level would not work. There are many other cases. For full list please refer here.

User-mode cache

User mode caching is maintained at worker process (w3wp.exe) level so it is more powerful and provide some more options than kernel mode caching.

advancecachingWhen we click on advance button it shows the below window

advancedoptinsIt allows to cache the data based on query-string variable and headers level which is very useful in certain scenarios.

So use this fantastic feature provided by IIS and get it benefited.

Cheers,
Brij

 

Learn AngularJs with me at C# Corner Delhi Developer’s Day on 28th June

Hello All,

C# Corner brings another full day event at its Noida office on 28th June. I’ll be discussing on one of the Hot technologies AngularJS and it will be fully interactive session with lots of demos. The event details are

Event Name – C# Corner Delhi Developer’s Day

Date – 28th June 2014

Time – 9:30 to 5:30 PM

Venue –  MCN Solutions Pvt. Ltd.
H-217, First Floor, Sector-63
Noida, Uttar Pradesh, INDIA

Is it free event? – Yes

For more detail and to register for the event Click here.

See you all at the event and learn the technology together.

Thanks,
Brij

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.

In last post, we first created a simple ASP.NET MVC project and displayed data in tabular format. We provided our Angular application, a proper structure and used controller, module and services . In that example, we loaded data while page load. We also discussed that there are two ways to load the data on UI and these are

  1. Get the HTML and data from the server while the page loads itself.
  2. Load the page first, then get the data via an AJAX call and update the page accordingly.

In today’s post, we will be using second approach and see that how can we initiate the Asynchronous AJAX request via AngularJS.

tworequestFor our example, we’ll pick the sample that we created in last post. Please do read last post before continuing. Inn last sample, the data is passed with the view itself which will not be the case here. So let’s make few changes in EventController.cs.

1- Don’t send the data with view. So Index action would look like as

public ActionResult Index()
{
        return View();
}

2- Let’s create a repository class (say EventRepository) that returns the data as required. It’ll help us further while scaling up this application. This repository has GetTalks  that returns array of talks as

public TalkVM[] GetTalks()
{
        var talks = new[]
        {
                new TalkVM { Id= "T001", Name= "Real Time Web Applications with SignalR", Speaker= "Brij Bhushan Mishra", Venue= "Hall 1", Duration= "45m" },
                new TalkVM { Id= "T002", Name= "Power of Node.js", Speaker= "Dhananjay Kumar", Venue= "Hall 2", Duration= "45m" },
                new TalkVM { Id= "T003", Name= "Getting started with AngularJS", Speaker= "Brij Bhushan Mishra", Venue= "Hall 1", Duration= "60m" },
                new TalkVM { Id= "T004", Name= "Microsoft Azure - Your cloud destination", Speaker= "Gaurav", Venue= "Hall 1", Duration= "45m" }
         };
         return talks;
}

3- Let’s change the GetTalks method of controller to GetTalkDetails and mark it as public because we’ll call it using AJAX.  Also change the return type as ActionResult. For that we created an instance of type ContentResult and return that. It internally calls EventRepository to get the talks and convert it to type ContentResult. It looks like

public ActionResult GetTalkDetails()
{
        var settings = new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() };

        var jsonResult = new ContentResult
        {
                Content = JsonConvert.SerializeObject(eventsRepository.GetTalks(), settings),
                ContentType = "application/json"
        };

        return jsonResult;
}

Now we have made changes at server side. We have a method GetTalkDetails that is ready to be called via AJAX.

So let’s move to Index.cshtml. As here we created an Angular Service that just read the data passed to the view. Now we don’t want that so let’s delete it. We’ll still need a service but that will initiate an AJAX call to get the data from the server. So let’s create a new file named EventsService.js.

Here we are going to use two inbuilt angular services. These are

1 $http – As the name suggest, it enable to initiate the AJAX request to the server and get the response. This is a core angular service and uses XMLHTTPRequest. This API can be paired with $q service to handle the request asynchronously. It’s syntax is similar to jQuery ajax if you have used that.

$q – This service exposes deferred and promise APIs. Defer API is used to expose the Promise instance. Promise returns the result when the asynchronous request successfully completes. It has also APIs that tells us whether the request got successful or unsuccessful.

We’ll use it in our example. Now it’s time to write the code in Angular service file.

eventModule.factory("EventsService", function ($http, $q) {
    return {
        getTalks: function () {
            // Get the deferred object
            var deferred = $q.defer();
            // Initiates the AJAX call
            $http({ method: 'GET', url: '/events/GetTalkDetails' }).success(deferred.resolve).error(deferred.reject);
            // Returns the promise - Contains result once request completes
            return deferred.promise;
        }
    }
});

In the above code, we are using $http and $q services both. In getTalks, we have created a deferred object using $q . Then used $http services to initiate the asynchronous request to the server to get the data. Based on the request status success and error callbacks are called. In success callback, we provided deferred.resolve and in case of error, deferred.reject. deferred.resolve resolves the derived promise with its value.

We also need to make changes in our controller.But why do we need to change the controller.?

Because the service method returns the Promise, not the actual value. While accessing the promise, response may not be received. So we cannot directly use it.To handle that, we need to use then, which gets fired once promise is resolved or rejected. It takes two functions as parameter, first gets called in case of success and second is called in case of error. Based on status of promise, it calls success or error one asynchronously. Let’s see the code

eventModule.controller("eventController", function ($scope, EventsService) {
    EventsService.getTalks().then(function (talks) { $scope.talks = talks }, function ()
    { alert('error while fetching talks from server') })
});

Now we have our application ready. So let’s run it
result
Great!! This is what we have expected.

Note – $http is a very powerful service and provide lots of features. I have just discussed the basic concept and feature around this.

The example application is attached with the post.

Happy Coding
Brij