Learning AngularJS – Part 3

Following on from my previous posts about AngularJS Learning AngularJS – The beginning and Learning AngularJS – Part 2. I would like to talk a bit about the form to add a person to my personnel application. My trials on how it went plus what I learnt along the way.

First of all, returning to the main page of the application. The page will always have a button to add a record and when the records are added, there will be a button to amend those records. So what happens when you click the add button. Soon as you hit the main page, the application makes use of the routing engine “#”, so that the application knows where to go, we add another entry into the module config saying that when #/addperson is called, use this controller and go to this template (sometimes called a partial). Example:

$routeProvider.when("/addNewPerson", {
controller: "newPeopleController",
templateUrl: "/templates/addNewPerson.html",
});

The addPerson.html is then injected into data-ng-view on the index.cshtml page.

The add person page is made slightly easier by the fact that I didn’t need to populate the form with data. However, a function to add a person is still needed in your service or factory (it is probably worth pointing out that although I used the terms there, my data service uses factory, confused?? Any examples that I seen have used factory when defining a service and most people can’t give you an answer when questioning the differencing between the two terms).

var _addPerson = function (newPerson) {
var deferred = $q.defer();


$http.post("/api/People", newPerson)
.then(function (result) {
var newlyCreatedPerson = result.data;
_people.splice(0, 0, newlyCreatedPerson);
deferred.resolve(newlyCreatedPerson);
},
function() {
deferred.reject();
});


return deferred.promise;
};

This function will go to the post method of the WebAPI people controller and save the input entered to the database. It uses a promise to return data to the controller, the promise is accessed through the deferred API in AngularJS. The resolve indicates a successful outcome and reject, an error or something isn’t right, and promise wraps it up and passes it back. In the dataservice, we can’t have bespoke controller functionality like error messages or redirecting to specific addresses. The promise allows the code to pass back the outcome to controller and the controller can do the details. It is probably worth pointing out that although I’ve used .then to define the outcome of my promises newer versions of AngularJS can use .success and .error. The final thing on the addPerson function is that splice will add the record into the personnel list without having to call the WebAPI get method again and the position specified.

The dataservice will have a public part to it in the return { addPerson = _addPerson }. The addPerson can be accessed in controllers, something like dataservice.addPerson so you don’t need to duplicate code. Good, right?

Hopefully now this should be making sense. The controller code is as follows:

function newPeopleController($scope, $http, $window, dataService)
{
$scope.newPerson = {};
$scope.salary = {};


$scope.save = function () {
dataService.addPerson($scope.newPerson)
.then(function () {
$window.location = "/#";
},
function() {
alert("Cannot save person");
});
};

The save() function is called in the html template by using ng-submit on the form tag . The data- bit is ro stop the editor complaining about the syntax.

In the HTML itself, there is couple of nice wee things. For example, I take advantage of the HTML5 required and placeholder attributes plus use ng-class=”{‘has-error’: AddNewPerson.salutation.$error.required}”. This will highlight the outline of the textbox in red if there is no text in a required field and then remove it as you type. Following on from that, I included the ng-disabled=”AddNewPerson.$invalid” tag so that the save button is disabled until all invalid data is removed. In addition, I use the ng-model attribute (ng-model=”newPerson.surname”) to gather up the data to post to the WebAPI method. Simple things but all good stuff.

Coupled with Bootstrap 3.0 to style the application it is all fairly lightweight and easy to learn so far.

Problems

In the first post I spoke about a problem relating to adding a person with an address but it was really the way that I was using the data and Automapper.

I think going forward the way that salary is entered has to change. The domain property is a list and I struggled to get the data into the list. Eventually I used an individual salary amount property and used Automapper to map it correctly. I may try to do this differently by changing the page to either use a table for salary and add to it or break the pages up to add person details first then salary. That’s a brief insight into my thinking now. Any thoughts welcome?

Until next time…