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.
Here 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
So 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
So here we can see the talk got added successfully. Sample is attached with the post.
To navigate to previous and next post of the series, use the links at the bottom of the post.
Thanks,
Brij
Reblogged this on Dinesh Ram Kali..
Very good, thanks!
Thanks!!
In each post..you are writing as “Sample is attached with the post.”, sorry but I couldn’t find it. Please help.
Thanks.
Not sure for which post you are talking. I have included sample wherever I have written in the post. Can you please let me know the posts where it is written but sample not availble?
Nicely structured and explained well, but I am feeling annoyed to move to next sequence of the tutorial once I am done with the current one. There is no previous and next button option given.
Thanks for your suggestion. I have added provided the links of my all my previous post in the series at start but not the next ones. I will update that. Thanks again
Pingback: Learning {{AngularJS}} with ASP.NET MVC – Part 5 | Code Wala