Wednesday, 10 December 2014

Some Guidelines to Design Clean Controller and Service

An AngularJS controller should not be burdened with other tasks other than mediating interaction between view and data that comes from one or more services. The data model, data management and application business logic should be written in services. I also like to use controllerAs with 'this' approach. Also include as few services as possible in the controller. If a controller has too many services then this should be questioned. Instead we should try to use services that aggregate other required services inside.

Below is an example of a controller:
myApp.controller('MedicineCtrl', ['medicineService',
 function (medicineService) {
     var vm = this;
     vm.medicineNames = medicineService.medicineNames;
     vm.addMedicine = function (input) {
         medicineService.addMedicine(input);
     };
     vm.updateMedicine = function (input) {
         medicineService.updateMedicine(input);
     };
     vm.deleteMedicine = function (id) {
         medicineService.deleteMedicine(id);
     };
}]);
Of course, this is a simplified example however this should give us a picture of what a controller should be designed like.

For the service, it's recommended to have 'private' variables and functions needed and only expose publicly the ones that are necessary as service object's properties. Also whenever possible, try to design the functions to run asynchronously using AngularJS promise (will show an example in the next post). Below is an example of a service:
myApp.factory('medicineService', ['otherService1', 'otherService2', 
  function (otherService1, otherService2) {
    // 'private' variables and functions
    var _medicines = [];
    var _privateVarOne;
    var _privateVarTwo;
    
    _addMedicine = function (input) {
       . . .
       // some business logic
       . . .
    };

    _updateMedicine = function (input) {
       . . .
       // some business logic
       . . .
    };

    _deleteMedicine = function (id) {
       . . .
       // some business logic
       . . .
    };

    _anotherPrivateFunction = function () {
       . . .
       // some business logic
       . . .
    };

    // only expose publicly the required members
    return {
        medicineNames: _medicineNames,
        addMedicine: _addMedicine,
        updateMedicine: _updateMedicine,
        deleteMedicine : _deleteMedicine 
    }
}]);

No comments: