1

The below code doesn't work because at the time the function is called this=window. I was expecting this = controller.actions.project but have since learned more about how this keyword works and now understand why that's not the case.

BROKEN

controller.actions = {
        project: new TableauAction("Project",
            function () {
                $http.get('/reports/projects/').then(function (response) {
                     this.options = response.data;
                });
            }};

The following solves the problem, but it is quite inelegant

WORKS

 controller.actions = {
        project: new TableauAction("Project",
            function () {
                var self = controller.actions.project;
                $http.get('/reports/projects/').then(function (response) {
                     self.options = response.data;
                });
            }};

TableauAction object:

function TableauAction(name, onChange) {
this.name = name;
this.onChange = onChange;}

My question is whether there is a more elegant way to access properties of the object from a function which is passed into it's constructor?

Jon Eastwood
  • 813
  • 10
  • 22
  • 1
    Be careful with "this", take a look at.. this: http://stackoverflow.com/questions/4195970/what-does-this-mean . In javascript, "this" assumes various values according to its context. In your case, the "this" inside the anonymous function and the "this" inside the callback get function are still different between them, hence you are forced to actually declare the self variable, as far as I know (or extend a very specific prototype in your class). – briosheje Jun 28 '16 at 09:55
  • That depends so much on what the constructor does with the function. Please show us the definition of `TableauAction`! – Bergi Jun 28 '16 at 10:18
  • Would `self = this` work? What's the context of the function you pass? – Bergi Jun 28 '16 at 10:20

1 Answers1

1

Add "this" context to your onChange callback.

function TableauAction(name, onChange) {
  this.name = name;
  this.onChange = onChange;
  //add this context to your onChange
  this.onChange.bind(this);
}

Then change the following to this:

controller.actions = {
        project: new TableauAction("Project",
            function () {
                //"this" refers to TableauAction instance now
                var $this = this;
                $http.get('/reports/projects/').then(function (response) {
                     //this refers to $http callback response..
                     $this.options = response.data;
                });
            }};
}
kemicofa ghost
  • 16,349
  • 8
  • 82
  • 131