-1

I have a Object that calls some async functions, using a prototype chain:

function Wow() {
  this.myAsyncFunction();
}

Wow.prototype.myAsyncFunction = function() {
  // Once my async function is complete, I fire a callback
  this.completed(); // Does not work
}

I would like to use it like this:

var wow = new Wow();
wow.completed = function() {
  alert('Awesome');
}

Here is a code snippet I created to simulate a my idea.

function Wow() {
    this.ok = document.getElementById('ok');
    this.wait();
}

Wow.prototype.wait = function() {
    this.ok.innerHTML = "Waiting..."
    window.setTimeout(function() {
        this.completed();
    }, 1000);
}


var wow = new Wow();
wow.completed = function() {
    wow.ok.innerHTML = "Compelted";
};
#ok {
    font-size: 28px;
    color: red;
}
<div id="ok"></div>

I spent more than a hour searching google and StackOverflow for a solution, but I'm finding difficulties to even search for it.

Oriol
  • 274,082
  • 63
  • 437
  • 513
Alberto
  • 399
  • 1
  • 6
  • 19
  • Put the actual context in the question. The problem you have in the external code is completely different to the problem you have in the code here. – Quentin Oct 05 '14 at 20:51
  • 2
    Whether you use the prototype or not doesn't really matter. It's about getting the wrong `this` context for the invocation of your callback. – Bergi Oct 05 '14 at 20:52
  • Sometimes you focus so much on *what you think* is the problem, that you loose sight of the real problem. I'm sorry for the duplicate question. – Alberto Oct 05 '14 at 20:56

2 Answers2

0

The problem with your code is that this isn't inherited among nested functions.

This works:

Wow.prototype.wait = function() {
    this.ok.innerHTML = "Waiting...";
    var that = this;
    window.setTimeout(function() {
        that.completed();
    }, 1000);
}

function Wow() {
    this.ok = document.getElementById('ok');
    this.wait();
}

Wow.prototype.wait = function() {
    this.ok.innerHTML = "Waiting...";
    var that = this;
    window.setTimeout(function() {
        that.completed();
    }, 1000);
}


var wow = new Wow();
wow.completed = function() {
    wow.ok.innerHTML = "Compelted";
};
#ok {
    font-size: 28px;
    color: red;
}
<div id="ok"></div>
Oriol
  • 274,082
  • 63
  • 437
  • 513
0

You need to change wait function a little bit, this is not available when setTimeOut runs the code, because that code is out of context this:

Wow.prototype.wait = function() {
    var self = this;
    this.ok.innerHTML = "Waiting..."
    window.setTimeout(function() {
        self.completed();
    }, 1000);
}

Working sample -- http://jsfiddle.net/4xcjhe8d/2/

MaximOrlovsky
  • 265
  • 2
  • 8