0

In my Angular module, I have a service like this one :

myApp.service( 'myService', function(){

    this.publicFunction1 = function(){
        ...
    };

    this.publicfunction2 = function(){
        ...
    };

    function privateFunction(){
        ...
    }
});

At a point, I need to call one of the "public" function from a private one, like this :

function somePrivateFunc(){
    this.publicFunction1();
    ...
}

But the element 'this' seems not to be visible inside the private function. How can I call publicFunction1() inside ?

Here is a workaround, but I'd like to understand plainly the situation. Can someone explain to me what happens here ? And is there a better way to do this ?

myApp.service( 'myService', function(){

    var service = this;

    this.publicFunction1 = function(){
        ...
    };

    this.publicfunction2 = function(){
        ...
    };

    function privateFunction(){
        service.publicFunction1();
        ...
    }
});
Eria
  • 2,653
  • 6
  • 29
  • 56
  • 1
    Define a variable like `var _this=this;` in service scope, then use the reference in private function like `_this.publicFunction1();` – Satpal Dec 03 '15 at 11:36
  • read this http://stackoverflow.com/questions/34064666/using-timeout-in-service-this-func-is-not-a-function – Jax Dec 03 '15 at 11:37

3 Answers3

6

Keep the reference of this variable outside and refer that everywhere like this:

myApp.service('myService', function() {
    var self = this;
    this.publicFunction1 = function() {
        ...
    };

    this.publicfunction2 = function() {
        ...
    };

    function privateFunction() {
        ...
    }

    function somePrivateFunc() {
        self.publicFunction1();
        ...
    }
});

Since the public function are part of the service,and the execution context for angular service is nothing but this keyword. But, since the private function(normal javascript function) is not part of the service, hence that function doesn't share same execution context. So for that private function the execution context is nothing but the global window object. So if you refer this inside of the private function you will get the window object. Therefore, to call the service function from normal javascript function(private function) we need to store the reference of angular this object.

Hope this clear your doubt.

Tushar
  • 1,115
  • 1
  • 10
  • 26
3

You can create a reference for this in a variable like:

myApp.service( 'myService', function(){
    var self = this; // creation of the variable here

    this.publicFunction1 = function(){
        ...
    };

    this.publicfunction2 = function(){
        ...
    };

    function privateFunction(){
        self.publicFunction1();
        ...
    }
});

EDIT: to explain why it's necessary, Angular is done on a basis of dependency injection (read here: https://docs.angularjs.org/guide/di). You will add 'myService' as a dependency in a controller for example and you will have access to the object created from the 'myService' definition.

You will be then able to call this.publicFunction1().

On the other hand, if you don't add this, this method won't exist in your controller.

Louis XIV
  • 2,224
  • 13
  • 16
  • Just figured it out before reading your post. But thanks ! Could you explain why is this necessary ? – Eria Dec 03 '15 at 11:40
  • OK, I tried to briefly explain the sense of this here, sorry my english is a bit rusted. – Louis XIV Dec 03 '15 at 11:54
0

Outside of the function, declare a variable like this:

var me = this;

Then you can refer to the 'outer' this from within the function.

Arj
  • 1,981
  • 4
  • 25
  • 45