Tuesday 26 January 2016

Angular.JS: using separated files for Controllers, Services, Applications modules

The starting point is an HTML application with only one HTML file with one Angular.js controller and one Angular.js service connected to the AngularJS application  :

<html>
   <head>
      <title>Angular JS Services</title>
   </head>
   <body>
      <h2>AngularJS Sample Application</h2>

      <div ng-app = "myApp" ng-controller = "CalcController">
         <p>Enter speed (m/s) : <input type = "number" ng-model = "speed" /></p>
         <p>Enter  time (s) : <input type = "number" ng-model = "duration" /></p>
         <button ng-click = "get_distance()">Hit for Result</button>
         <p>The distance will be (m) : {{distance}} </p>
      </div>

      <script src = "http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
      <script>
         angular.module("myApp", []);
         angular.module("mainApp"),service('CalcService', function(){
            this.get_distance = function(speed,duration) {
               return speed * duration ;
            }
         });
         angular.module("myApp").controller('CalcController', function($scope, CalcService) {
            $scope.speed = 0;
            $scope.duration = 0;
            $scope.distance = 0;
            $scope.get_distance = function() {
                $scope.distance = CalcService.get_distance($scope.speed,$scope.duration);
            }
         });
      </script>
   </body>
</html>

The aims of this post is to transfer js code into separated files to have a clear separation by module:  we will have put some links to js files within the HTML file in order to replace the  js code  .

<script src = "http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>   
<script src="js/usingService/app.js"></script>
<script src="js/usingService/controllers.js"></script>
<script src="js/usingService/services.js"></script>

with the following files :

app.js :
angular.module('myApp', [
  'myApp.services',
  'myApp.controllers'
]);

controllers.js
angular.module('myApp.controllers', []).
    controller('CalcController', function($scope,CalcService) {
        $scope.speed= 0;
        $scope.duration = 0;
        $scope.distance = 0;
        $scope.get_distance = function() {
                $scope.distance =  CalcService.get_distance($scope.speed,$scope.duration);
        } 
});

services.js
angular.module('myApp.services', [])
.service('CalcService', function(){
            this.get_distance = function(speed,duration) {
               return speed * duration;
          }
 });


Note: 

  • Another way to do it is to develop using the Angular Seed Project (it gives a great help for starting development offering a nice project structure with separated files) - see https://github.com/angular/angularseed/tree/69c9416c8407fd5806aab3c63916dfcf0522ecbc
  • We could have use no trigger button : 
<html>
<head>  
<title>Angular JS Services</title>
<script src = "http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>   </head>
   <body>
      <h2>AngularJS Sample Application</h2>
      <div ng-app = "myApp" ng-controller = "CalcController">
         <p>Enter speed (m/s) : <input type = "number" ng-model = "speed" /></p>
         <p>Enter  time (s) : <input type = "number" ng-model = "duration" /></p>
         <p>The distance will be (m) : {{distance()}} </p>
      </div>
      <script>
         angular.module("myApp", []);
          angular.module("myApp").service('CalcService', function(){
            this.get_distance = function(speed,duration) {
               return speed * duration ;
            }
         });
          angular.module("myApp").controller('CalcController', function($scope, CalcService) {

            $scope.speed = 0;
            $scope.duration = 0;
            $scope.distance = function() {
                return CalcService.get_distance($scope.speed,$scope.duration);
            }
         });
      </script>
   </body>
</html>
  • Here, we decided to use the MVC pattern since that is the best way to organize any project development; however, for such a simple case, we should better use the MVVM  pattern : this consists on deleting the script part  and replacing {{distance()}}  by {{time *  duration }} (no controller in such case!!)
  • Use PacalCase for the names of controllers, and camelCase for the application module 's name

http://plnkr.co/edit/txnu4yECXnotzu3BqfzK