Home » Angularjs » How can I test an AngularJS service from the console?

How can I test an AngularJS service from the console?

Posted by: admin November 2, 2017 Leave a comment

Questions:

I have a service like:

angular.module('app').factory('ExampleService', function(){
  this.f1 = function(world){
    return 'Hello '+world;
  }
  return this;
})

I would like to test it from the JavaScript console and call the function f1() of the service.

How can I do that?

Answers:

So I found out that you can not simply call angular.injector(['app']) if there already exists an injector. Because this function tries to create a new injector.

Instead you have to call injector = angular.element(document.body).injector()

From the retrieved injector you can then get whatever service you like with injector.get('ServiceName')

So in one line the command would look like this:

angular.element(document.body).injector().get('serviceName')

More information on that in this answer: Can't retrieve the injector from angular
And even more here: Call Angular JS from legacy code


Another useful trick to get the $scope of a particular element.
Select the element with the DOM inspection tool of your developer tools and then run the following line ($0 is always the selected element):
angular.element($0).scope()

Questions:
Answers:

First of all, a modified version of your service.

a )

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

app.factory('ExampleService',function(){
    return {
        f1 : function(world){
            return 'Hello' + world;
        }
    };
});

This returns an object, nothing to new here.

Now the way to get this from the console is

b )

var $inj = angular.injector(['app']);
var serv = $inj.get('ExampleService');
serv.f1("World");

c )

One of the things you were doing there earlier was to assume that the app.factory returns you the function itself or a new’ed version of it. Which is not the case. In order to get a constructor you would either have to do

app.factory('ExampleService',function(){
        return function(){
            this.f1 = function(world){
                return 'Hello' + world;
            }
        };
    });

This returns an ExampleService constructor which you will next have to do a ‘new’ on.

Or alternatively,

app.service('ExampleService',function(){
            this.f1 = function(world){
                return 'Hello' + world;
            };
    });

This returns new ExampleService() on injection.

Questions:
Answers:

@JustGoscha’s answer is spot on, but that’s a lot to type when I want access, so I added this to the bottom of my app.js. Then all I have to type is x = getSrv('$http') to get the http service.

// @if DEBUG
function getSrv(name, element) {
    element = element || '*[ng-app]';
    return angular.element(element).injector().get(name);
}
// @endif

It adds it to the global scope but only in debug mode. I put it inside the @if DEBUG so that I don’t end up with it in the production code. I use this method to remove debug code from prouduction builds.