[Dev Tip] 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

1
2
3
4
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

1
2
3
4
5
6
7
8
9
10
11
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

1
2
3
4
5
6
7
8
9
10
11
12
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.

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

1
2
3
4
5
6
7
8
9
10
11
12
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 anderror 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

1
2
3
4
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

Advertisements

One thought on “[Dev Tip] Learning {{AngularJS}} with ASP.NET MVC – Part 4

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s