Mark
Mark

Reputation: 57

How to call a method from a JS file in Angular?

I have test.js which contains:

function test(str) {
    return 'Hello, ' + str + '!'
}

I want to use the test method in my Angular controller:

angular.module('testModule')
.controller('testController', ['$scope', function($scope){
    console.log(test('John'))
}

Which returns Hello, John!

I have tried:

<div ng-app="testModule" ng-controller="testController">
    <script type="text/javascript">
        function test(str) {
            return 'Hello, ' + str + '!'
        }
    </script>
</div>

Which works as expected, returning Hello, John!. But trying to reference the method from my other .js files return ReferenceError: ____ is not defined.

  1. How can I call methods from other .js files in my Angular controller?
  2. What is the best practice to call these methods? (e.g. Do I have to transfer the code in all my .js files into Angular's model or controller?)

Upvotes: 1

Views: 1382

Answers (2)

Ruan Mendes
Ruan Mendes

Reputation: 92324

You should create a service for singleton objects. In production, you feed it live objects, and during test you can give it mock objects. See http://jsfiddle.net/mendesjuan/E9bU5/235/

You could go against what Angular provides and use globals (like jQuery or toaster) right from your controller.

angular.
module('testModule', []).
 controller('testController', ['$scope','test', function ($scope, test) {
   $scope.callTest = function(msg) {
     return test(msg);
   };
 }]).
factory('test', [function() {
   return function(msg) {
     return 'Hello, ' + str + '!';
   } 
}]);

// Just some global
window.myTest = function() {
    return "I'm in";
};


angular.
module('testModule', []).
 controller('testController', ['$scope','test', function ($scope, test) {
   // This will be easy to test because it's using a service that can be mocked
   $scope.callTest = function(msg) {
     return test(msg);
   };
   // This will be hard to test because it is touching a global
   $scope.myTest = function() {
      return myTest();
   }
 }]).
factory('test', ['$window', function(str) {
   return function(str) {
       return 'Hello, ' + str + '!'
   }
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="testModule" ng-controller="testController">
    <!-- Show the name in the browser -->
     <h1>{{ callTest('You') }}</h1>
     <h1>{{ callTest('Me') }}</h1>
     <h1>{{ myTest() }}</h1>
</div>

Upvotes: 2

Dave
Dave

Reputation: 4412

First, you create a service in your module. (There are several slightly different ways to create a service, depending on your needs. I'll let the angular purists argue those if they want.)

angular.module("testModule")
    .factory("testService", function() {
        return {
            sayHello: function(str) { 'Hello, ' + str + '!';}
        }
    });

Then you can inject that service into your controller:

angular.module('testModule')
    .controller('testController', ['$scope', 'testService', function($scope, testService){
        console.log(testService.sayHello('John'));
    });

Note that because of how angular handles inject, you don't need to run these in order. You can define the controller first, and angular will still inject the service into it for you.

Upvotes: 0

Related Questions