2

How can I get the name of a service (or factory, provider, controller, directive...) from WITHIN the object? Eg

angular.module('app', []).controller('myCtrl', function() {
  // how do I get the name 'myCtrl' here?
})

The obvious way is hard coding, but I want to avoid that

.service('myService', function() {
  this.name = 'myService';
});

I guess this is a way, but I'm hoping to avoid it as I don't want to have to declare globals in my app

var myCtrlName = 'myCtrl';
angular.module('app', []).controller(myCtrlName, function() {
  console.log(myCtrlName);
});
4
  • Why do you even need this? The moment you depend on names in your code you'll run into problems. Commented Oct 16, 2014 at 10:07
  • @Yoshi I want to use it to register callbacks with a mediator service. I pass the name of the service to the mediator in an .init so the mediator has an id for each service. Mediator connects endpoints a bit like $routeProvider.when('/', {templateUrl:'views/main.html',controller: 'myCtrl',...}), which also relies on names, and is an accepted (indeed celebrated) pattern in Angular. Do you have another suggestion? Commented Oct 16, 2014 at 10:30
  • Angulars use of names always relys on the fact that at one time the element in question was registered under that specific name. It's never guessed or similar, it's always a setter/getter relationship. I'm not sure whether what you're trying to do is the same concept. Also from your comment with regards to your question, this looks like a X-Y Problem. Commented Oct 16, 2014 at 10:55
  • @Yoshi :D Yes, possibly an X-Y Problem. I've already built a successful "X" without too much fumbling (I think!). I just wanted to remove the hard coded names ("Y"). Commented Oct 16, 2014 at 12:07

4 Answers 4

2

Define your service name as a variable so you can reuse, then wrap in a closure to avoid creating a global variable.

var app = angular.module('app', []);
(function () {
    var serviceName = "myService";
    app.service(serviceName, function () {
        this.name = serviceName;
    });
})();    
Sign up to request clarification or add additional context in comments.

Comments

1

Ok, this is how to do it, but be aware, it's very dirty and it uses undocumented stuff from angular :D

var app = angular.module('app', []);
app.controller("Ctrl", function($scope, Serv) {

});
app.service("Serv", function() {
  //We're gonna compare functions, the current one and the one registered in the invokeQueue of the app
  var callee= arguments.callee;
  //Loop the invokeQueue 
  _.each(app._invokeQueue, function(inv) {
    //Check if the functions match
    if(inv[2][1] === callee) {
      //Print the name of the current service!
      console.log(inv[2][0]);
    }
  });
});

Check this jsbin to see it in action: http://jsbin.com/yugogonoya/edit?html,js,console,output

1 Comment

Too dirty to accept as the answer, but +1 for your ingenuity. I would love to have you on my team. :)
0

I think, that it's not possible to get service/factory name.

If we are talking about controller name, it's possible with subscription on $routeChangeSuccess event.

$scope.$on('$routeChangeSuccess', function () {
     console.log($route.current.controller);
});

Also, if we are talking about directive. You can use this trick.

app.directive('directiveOne', function (){
  return {
    controller: 'SomeCtrl',
    scope: true,
    template: '<button ng-click="myFun()">Test A</button>',
    link: function(scope, elem, attrs, ctrl) {
      ctrl.directiveName = 'directiveOne';
    }
  };
});

app.directive('directiveTwo', function (){
  return {
    controller: 'SomeCtrl',
    scope: true,
    template: '<button ng-click="myFun()">Test B</button>',
    link: function(scope, elem, attrs, ctrl) {
      ctrl.directiveName = 'directiveTwo';
    }
  };
});

app.controller('SomeCtrl', function ($scope){
    var ctrl = this;
    $scope.test = function (){
       console.log('Directive name is: ' + ctrl.directiveName);
    };
});

1 Comment

Re your directive trick, it's always possible to hard code the name of a service the same way angular.module('app', []).service('myService', function() { this.name = 'myService' }). That's the other method I'm trying to avoid (just added to my question!)
0

If you are using ui-router you can learn the name of the controller through $state service.

$state.current.controller;

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.