Reputation: 1879
I am trying to access a function A from a function in a function in A eg:
functionA () {
functionB () {
functionC () {
#want to call functionA from here
}
}
}
here is the code I am using:
updateProgress: function (statusurl){
axios({
method: 'get',
url: statusurl,
dataType: 'json',
headers: {'Content-Type': 'application/json; charset=utf-8'},
async: true,
data: {}
})
.then(function (response) {
var data = response.data
if (data['state'] !== 'PENDING' && data['state'] !== 'PROGRESS') {
if ('result' in data) {
// show result
console.log('result: ' + data['result'])
}
else {
// something unexpected happened
console.log('state: ' + data['state'])
}
}
else {
// rerun in 2 seconds
setTimeout(function() {
this.updateProgress(statusurl)
}, 2000)
}
}.bind(this))
.catch(e => {
console.log('error: ' + e)
})
As you can see I am using this.functionA from functionC and bind() on functionA.
I get the following error in the console:
Uncaught TypeError: this.updateProgress is not a function at eval
Any idea on how to do this?
Upvotes: 1
Views: 72
Reputation: 29122
The problem is that the value of this
has changed. Every time you enter a new function (as declared with the function
keyword) the value of this
changes. In this specific case it is the function called by setTimeout
that is at fault:
setTimeout(function() {
this.updateProgress(statusurl)
}, 2000)
In years gone by the solution would be to grab a reference to this
under a different name:
var me = this
setTimeout(function() {
me.updateProgress(statusurl)
}, 2000)
Slightly less old-school would be using bind
, like you have for the other nested function:
setTimeout(function() {
this.updateProgress(statusurl)
}.bind(this), 2000)
If you have ES6 arrow functions available (and judging by your catch
it would seem you have) then you don't even need to use bind
. Arrow functions don't change the value of this
so you can just write:
setTimeout(() => {
this.updateProgress(statusurl)
}, 2000)
Your other use of bind
can similarly be removed.
Upvotes: 3