14

i want to write a function inside a angularjs service and i want to reuse it in all my

controllers.

var mod= angular.module('myapp', ['eventFilters', 'highlight', 'event', 'dayfilter', 'Services']).
config(['$routeProvider', function($routeProvider) {
$routeProvider.
      when('/', {templateUrl: 'template.html',   controller: Ctrl}).
      when('/temp', {templateUrl: 'temp.html',   controller: tempCtrl}).
      otherwise({redirectTo: '/invalid'});
}]);
mod.service ('sharedService', function() {
function daysInMonth(month,year) {
    return new Date(year, month+1,0).getDate();
}
});

i want to use the daysInMonth function in any of my controller. is it possible? if so could anyone explain me briefly with some examples in fiddle.

Thanks in advance

0

6 Answers 6

26

Here is fiddle with a basic example of how you can use (inject) services in controllers.

http://jsfiddle.net/uhmNR/1/

var myApp = angular.module('myApp',[]);


//Here is the service Users with its functions and attributes
//You can inject it in any controller, service is a singleton and its data persist between controllers
myApp.factory('Users', function () {

    var userName = "John Doe";

    return {
        getUserName: function () {
             return userName;                   
        },
        setUserName: function (newName) {
            userName = newName;
        }
    }
});

//An Util service with DaysInMonth method   
myApp.factory('Util', function () {

    return {
        daysInMonth: function (month,year) {

            return new Date(year, month+1,0).getDate();
        }
    };

});   

//Here I am injecting the User service andusing its methods   
myApp.controller('MyCtrl', ['$scope', 'Users', 'Util', function ($scope, Users, Util) {

    Users.setUserName('Robin Hood');

    $scope.name = Users.getUserName();

    //Using Util.daysInMonth()
    $scope.date = Util.daysInMonth(12,2012);
}]);

Hope It helps.

Sign up to request clarification or add additional context in comments.

Comments

6

Expose the function as a service, then let the AngularJS injector do the rest. You can easily set a daysInMonth service as a static value in your module. See this in action at http://jsfiddle.net/hbulhoes/zdtnw/

var mod = angular.module('myapp', []);

// This is the declaration of the daysInMonth service. It's set as
// a value in the module, with the value being the very function
// you want to share among other services and controllers:
mod.value('daysInMonth', function(month, year) {
    return new Date(year, month+1,0).getDate();
});

// And this is an example controller that depends on the daysInMonth function.
function MyController($scope, daysInMonth){
    $scope.DaysInCurrentMonth = daysInMonth(12, 2012);
}

1 Comment

Nice usage of value() -- I haven't seen too many examples of that.
1

If you want a function to be available to all of your controllers, you might consider defining the method on $rootScope, instead of using a service:

myApp.run(function($rootScope) {
    $rootScope.daysInMonth = function(year, month) {
        return new Date(year, month+1,0).getDate();
    }
});

Then, due to prototypal scope inheritance, all of your controllers' scopes will have access to the method (without the need for dependency injection). You can call it in any controller like so:

function MyCtrl($scope) {
   console.log($scope.daysInMonth(12, 2012));
}​

JavaScript won't find function daysInMonth defined on $scope, so it will look in the parent scope (in this case the root scope) for the function, and it will find it.

5 Comments

thanks a lot. actually wat is the diff b/w rootscope and scope?
There is only one root scope. There are many other scopes. ng-controller, ng-repeat, ng-include, and some directives create new scopes. Read more: $rootScope, Scopes
According to Angular.js convention, rootScope should not be used for that kind of stuff.
@dman, I agree in general with the principle, but if all controllers need this, I would probably put it in $rootScope (with a comment) rather than inject it everywhere.
@Mark Rajcok, but if by chance you've some controllers that are linked to isolate scopes, you'll have to inject the $rootScope in all of them and end up with a lot of injections as well, but of a very generic thing. Or am I wrong?
1

You need to expose it. Wrap it in a return block:

var mod= angular.module('myapp', ['eventFilters', 'highlight', 'event', 'dayfilter', 'Services']).
config(['$routeProvider', function($routeProvider) {
$routeProvider.
  when('/', {templateUrl: 'template.html',   controller: Ctrl}).
  when('/temp', {templateUrl: 'temp.html',   controller: tempCtrl}).
  otherwise({redirectTo: '/invalid'});
}]);
mod.service ('sharedService', function() {
   return {
      daysInMonth: function(month,year) {
         return new Date(year, month+1,0).getDate();
      }
   };
});

Comments

0

If you want to use the actual Angular Service (not factory, or provider), then all you have to do is the following to create something the Angular way.

mod.service ('sharedService', function() {
  function daysInMonth(month,year) {
    return new Date(year, month+1,0).getDate();
  }
});

// Would turn into 

mod.service("sharedService", function(){
  this.daysInMonth(month, year){
    return new Date(year, month + 1, 0).getDate();
  }
});

You should not RETURN from a service unless you NEED to override the default THIS object that will be created when the service is NEW'ED. In that case, you can return an Object Literal, Function Definition, Array, most Objects excluding any primitives. Just assure you ask the question "why do I need to override the default behavior?"

That's really the entire point of a service. When you inject the SERVICE Angular will NEW the function you pass, thus returning it to you as described. In your case, the service will be exactly what you need. Angular will build the Service just once, and the new sharedService function result will be available throughout your application, but only when the service is DI'd at least once somewhere in your application. If you don't DI it, then the service will never be created as it is lazily loaded (Factory and Service).

If you find you really want to return something, (although you CAN do it in a service), the appropriate place would be in an Angular Factory. In fact, if you DON'T return from a Factory you will get a nice little notice

ERROR: Provider 'sharedService' must return a value from $get factory method.

NOTE: where the $get function is the second argument of the service function definition.

mod.factory("sharedService", function(){
  function daysInMonth(month, year){
    return new Date(year, month + 1, 0).getDate();
  }

  return {
    daysInMonth: daysInMonth
  }

  // Or you could do this...
  return daysInMonth;
});

When using the Angular Factory you no longer get a NEW'ED function, which is why a return must be created.

Comments

0

I think the OP meant the service is a function, like for example the $timeout function. As the default service factory makes a "service" of whatever you return, you can do this:

angular.module('myApp.myModule',[])
.factory('add',['$injectables',function($injectables) {
  return function(arg1,arg2)
  {
    //this is the function that will be called when you use this service
    return arg1 + arg2;
  }
}]);

Usage:

angular.module('myApp.Othermodule',['myApp.myModule'])
.controller('controllername',['add',function(add) {

  //controller code and somehwere
  $scope.z = add($scope.x,$scope,y);
}]);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.