Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I add some small utility functions to my AngularJS application?

Tags:

angularjs

People also ask

Which function is used to create a module in AngularJS?

module() method creates an application module, where the first parameter is a module name which is same as specified by ng-app directive.

What are AngularJS functions?

The controller in AngularJS is a JavaScript function that maintains the application data and behavior using $scope object. You can attach properties and methods to the $scope object inside a controller function, which in turn will add/update the data and attach behaviours to HTML elements.

Can we have two ng-app in AngularJS?

Only one ngApp directive can be auto-bootloaded per HTML Document but you can have multiple apps as long as you manually bootstrap the subsequent ones.


EDIT 7/1/15:

I wrote this answer a pretty long time ago and haven't been keeping up a lot with angular for a while, but it seems as though this answer is still relatively popular, so I wanted to point out that a couple of the point @nicolas makes below are good. For one, injecting $rootScope and attaching the helpers there will keep you from having to add them for every controller. Also - I agree that if what you're adding should be thought of as Angular services OR filters, they should be adopted into the code in that manner.

Also, as of the current version 1.4.2, Angular exposes a "Provider" API, which is allowed to be injected into config blocks. See these resources for more:

https://docs.angularjs.org/guide/module#module-loading-dependencies

AngularJS dependency injection of value inside of module.config

I don't think I'm going to update the actual code blocks below, because I'm not really actively using Angular these days and I don't really want to hazard a new answer without feeling comfortable that it's actually conforming to new best practices. If someone else feels up to it, by all means go for it.

EDIT 2/3/14:

After thinking about this and reading some of the other answers, I actually think I prefer a variation of the method brought up by @Brent Washburne and @Amogh Talpallikar. Especially if you're looking for utilities like isNotString() or similar. One of the clear advantages here is that you can re-use them outside of your angular code and you can use them inside of your config function (which you can't do with services).

That being said, if you're looking for a generic way to re-use what should properly be services, the old answer I think is still a good one.

What I would do now is:

app.js:

var MyNamespace = MyNamespace || {};

 MyNamespace.helpers = {
   isNotString: function(str) {
     return (typeof str !== "string");
   }
 };

 angular.module('app', ['app.controllers', 'app.services']).                             
   config(['$routeProvider', function($routeProvider) {
     // Routing stuff here...
   }]);

controller.js:

angular.module('app.controllers', []).                                                                                                                                                                                  
  controller('firstCtrl', ['$scope', function($scope) {
    $scope.helpers = MyNamespace.helpers;
  });

Then in your partial you can use:

<button data-ng-click="console.log(helpers.isNotString('this is a string'))">Log String Test</button>

Old answer below:

It might be best to include them as a service. If you're going to re-use them across multiple controllers, including them as a service will keep you from having to repeat code.

If you'd like to use the service functions in your html partial, then you should add them to that controller's scope:

$scope.doSomething = ServiceName.functionName;

Then in your partial you can use:

<button data-ng-click="doSomething()">Do Something</button>

Here's a way you might keep this all organized and free from too much hassle:

Separate your controller, service and routing code/config into three files: controllers.js, services.js, and app.js. The top layer module is "app", which has app.controllers and app.services as dependencies. Then app.controllers and app.services can be declared as modules in their own files. This organizational structure is just taken from Angular Seed:

app.js:

 angular.module('app', ['app.controllers', 'app.services']).                             
   config(['$routeProvider', function($routeProvider) {
     // Routing stuff here...
   }]);  

services.js:

 /* Generic Services */                                                                                                                                                                                                    
 angular.module('app.services', [])                                                                                                                                                                        
   .factory("genericServices", function() {                                                                                                                                                   
     return {                                                                                                                                                                                                              
       doSomething: function() {   
         //Do something here
       },
       doSomethingElse: function() {
         //Do something else here
       }
    });

controller.js:

angular.module('app.controllers', []).                                                                                                                                                                                  
  controller('firstCtrl', ['$scope', 'genericServices', function($scope, genericServices) {
    $scope.genericServices = genericServices;
  });

Then in your partial you can use:

<button data-ng-click="genericServices.doSomething()">Do Something</button>
<button data-ng-click="genericServices.doSomethingElse()">Do Something Else</button>

That way you only add one line of code to each controller and are able to access any of the services functions wherever that scope is accessible.


Coming on this old thread i wanted to stress that

1°) utility functions may (should?) be added to the rootscope via module.run. There is no need to instanciate a specific root level controller for this purpose.

angular.module('myApp').run(function($rootScope){
  $rootScope.isNotString = function(str) {
   return (typeof str !== "string");
  }
});

2°) If you organize your code into separate modules you should use angular services or factory and then inject them into the function passed to the run block, as follow:

angular.module('myApp').factory('myHelperMethods', function(){
  return {
    isNotString: function(str) {
      return (typeof str !== 'string');
    }
  }
});

angular.module('myApp').run(function($rootScope, myHelperMethods){ 
  $rootScope.helpers = myHelperMethods;
});

3°) My understanding is that in views, for most of the cases you need these helper functions to apply some kind of formatting to strings you display. What you need in this last case is to use angular filters

And if you have structured some low level helper methods into angular services or factory, just inject them within your filter constructor :

angular.module('myApp').filter('myFilter', function(myHelperMethods){ 
  return function(aString){
    if (myHelperMethods.isNotString(aString)){
      return 
    }
    else{
      // something else 
    }
  }
);

And in your view :

{{ aString | myFilter }}   

Do I understand correctly that you just want to define some utility methods and make them available in templates?

You don't have to add them to every controller. Just define a single controller for all the utility methods and attach that controller to <html> or <body> (using the ngController directive). Any other controllers you attach anywhere under <html> (meaning anywhere, period) or <body> (anywhere but <head>) will inherit that $scope and will have access to those methods.


The easiest way to add utility functions is to leave them at the global level:

function myUtilityFunction(x) { return "do something with "+x; }

Then, the simplest way to add a utility function (to a controller) is to assign it to $scope, like this:

$scope.doSomething = myUtilityFunction;

Then you can call it like this:

{{ doSomething(x) }}

or like this:

ng-click="doSomething(x)"

EDIT:

The original question is if the best way to add a utility function is through a service. I say no, if the function is simple enough (like the isNotString() example provided by the OP).

The benefit of writing a service is to replace it with another (via injection) for the purpose of testing. Taken to an extreme, do you need to inject every single utility function into your controller?

The documentation says to simply define behavior in the controller (like $scope.double): http://docs.angularjs.org/guide/controller


Here is a simple, compact and easy to understand method I use.
First, add a service in your js.

app.factory('Helpers', [ function() {
      // Helper service body

        var o = {
        Helpers: []

        };

        // Dummy function with parameter being passed
        o.getFooBar = function(para) {

            var valueIneed = para + " " + "World!";

            return valueIneed;

          };

        // Other helper functions can be added here ...

        // And we return the helper object ...
        return o;

    }]);

Then, in your controller, inject your helper object and use any available function with something like the following:

app.controller('MainCtrl', [

'$scope',
'Helpers',

function($scope, Helpers){

    $scope.sayIt = Helpers.getFooBar("Hello");
    console.log($scope.sayIt);

}]);