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 Factory 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 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. In 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 from the server using AJAX. Now we don’t want it in View that so let’s delete it. 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 suggests, 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.

To navigate to previous and next post of the series, use the links at the bottom of the post.

Happy Coding
Brij

[12th Aug 2015 : Updated this post for Angular version 1.4.*]

6 thoughts on “Learning {{AngularJS}} with ASP.NET MVC – Part 4

  1. Pingback: Learning {{AngularJS}} with ASP.NET MVC – Part 6 | Code Wala

  2. Really impressed with your work following angular .Keep up the good work you have one of the best and easy to understand way to explain things 😉

  3. Very interesting post in the series. Could go a step further and pass the Url into the ‘getData’ service function. Nice work!

  4. Pingback: Learning {{AngularJS}} with ASP.NET MVC – Part 3 | Code Wala

Leave a comment