0

I have written the following code, which runs:

app.config(['$stateProvider', function ($stateProvider) {
    $stateProvider
        .state('editor', {
            resolve: {
                init: ['codeService', function (codeService) {
                    return codeService.init()
                }]
            }
            ...
        })

app.service('codeService', ['$http', function ($http) {
    this.init = function () {
        initFolder()
        ...
    }

    var initFolder = function () {
        // the code inside does not mention "this"
        ...
    }
}    

I realise that, to use codeService.init in reslove, I need to define init with this, while initFolder can be defined as private method. However, the following definition does not work:

    this.init = function () {
        this.initFolder()
        ...
    }

    this.initFolder = function () {
        // the code inside does not mention "this"
        ...
    }

Does anyone know why I could not define initFolder with this?

SoftTimur
  • 8,904
  • 23
  • 106
  • 212

2 Answers2

2

Create a reference to this outside of the function and use that inside the functions. This way you have a reference to this at the time you define the functions and reuse that reference inside the functions, otherwise this could point to something different at the time the method is actually called like the browser window.

var me = this;
this.init = function () {
    // reference to this
    me.initFolder()
    ...
}

I recommend reading over How does the "this" keyword work?, it has a very well written answer.

Community
  • 1
  • 1
Igor
  • 55,253
  • 10
  • 80
  • 149
1

This has to do with the way this behaves inside boxed scope in javascript.

Eg:

var obj = {
    firstname: "rahul",
    lastname: "arora"
    getName: function(){
         console.log(this);//will output the object as this here points to the object it is defined under
    }
};

obj.getName();

WHEREAS

var obj = {
    firstname: "rahul",
    lastname: "arora"
    getName: function(){

          function getFullName(){
              console.log(this);//this refers to the window and not to the object this time
          }
          getFullName();
    }
};

obj.getName();

That is how javascript works. Its a little weird, but this is how it is designed.

Applying the same concept to your AngularJS Service

When you call your service, you are doing nothing but calling a constructor function to make an instance of that object which you can use.

All the methods that you use are then linked to an object instance passed to your controller which you then use.

Now when a function is defined inside that object which is not directly under that service, this does not behave correctly for that because of the concept explained above.

Therefore you have to store the value of this in some variable to use it further inside a function.

In your specific case you can make it work as:

var self = this;

this.init = function () {
    self.initFolder()
    /*since the function is called from inside a function which is    inside an object, 
    this will not point to that instance of the object in this    scenario. 
    Therefore, you have to store the value of this in a variable to make sure you use that inside this function to make it work properly.*/
    ...
}

this.initFolder = function () {
    // the code inside does not mention "this"
    ...
}
Rahul Arora
  • 4,217
  • 1
  • 14
  • 22