Reputation: 18034
I have an Object with the variable "parentVar", and I want to write the response of an ajax-request into it. Sounds easy, but I'm not able to do this, due to some namespace-troubles.
I wrote a very minimalistic example, which shows the problem.
The ajax-request will be started, when I call the Object's init-Function:
var parentObj = new Parent();
//Do some work (I need some functionality from the object before it can be fully initialized)
alert("Old Value = " + parentObj.parentVar);
parentObj.init(function(){
alert("New Value = " + parentObj.parentVar);
});
The init-Function calls the Function "load" which performs an Ajax-Request, and returns the received data (in another callback-Function).
function Parent(){
this.parentVar = "old"; //this value should be replaced
this.init = function(initCallBack){
this.load(function(newData){ //load the content of the file
this.parentVar = newData; //write the content into the variable
initCallBack(); //I'm done!
});
}
this.load = function(callbackFunc){
//load the new value from a file via ajax (asyncron).
//When finished: call callbackFunc
callbackFunc("newValue");
}
}
I already tried passing the scope to the loader-function, and getting it back in the callBack-Function. But it didn't work.
I also tried "var parentscope = this;
" in the init-Function,
and "parentscope.parentVar = newData;
" - it didn't work either.
Is it possible to achieve this with parentVar being private? (I mean "var parentVar = 'old';
" instead of "this.parentVar = 'old';
").
Upvotes: 3
Views: 591
Reputation: 150020
The callback function passed to load()
doesn't have the value of this
that you want. The way you call that function this
will be window
. You can bind the value of this
as follows:
this.load(function(newData){ //load the content of the file
this.parentVar = newData; //write the content into the variable
initCallBack(); //I'm done!
}.bind(this));
...and then it will work: http://jsfiddle.net/v9Hvb/
Is it possible to achieve this with
parentVar
being private? (I meanvar parentVar = 'old';
instead ofthis.parentVar = 'old';
).
You can use a private variable inside the Parent()
constructor and it will be accessible within all of the methods defined inside the constructor. But it won't be accessible outside with parentObj.parentVar
so you'd have to add a getter method.
It would be easier to use a private var self = this;
variable inside the Parent()
constructor and then use self
instead of this
in the methods:
function Parent(){
var self = this;
self.parentVar = "old"; //this value should be replaced
self.init = function(initCallBack){
self.load(function(newData){ //load the content of the file
self.parentVar = newData; //write the content into the variable
initCallBack(); //I'm done!
});
}
self.load = function(callbackFunc){
//load the new value from a file via ajax (asyncron).
//When finished: call callbackFunc
callbackFunc("newValue");
}
}
Demo: http://jsfiddle.net/v9Hvb/1/
Further reading: MDN's this
article
Upvotes: 1
Reputation: 3669
The problem is that the this
within the callback passed to the load within the init function doesn't refer to the Parent
object but the window
object. There is a well known hack for this: save the reference to the Parent's this
in _this
. Other variable names commonly used are that
and self
and all these prefixed with more underscores. Here is a code that works:
function Parent(){
this.parentVar = "old"; //this value should be replaced
var _this = this;
this.init = function(initCallBack){
this.load(function(newData){ //load the content of the file
_this.parentVar = newData; //write the content into the variable
initCallBack(); //I'm done!
});
}
this.load = function(callbackFunc){
//load the new value from a file via ajax (asyncron).
//When finished: call callbackFunc
callbackFunc("newValue");
}
}
Upvotes: 1