.bind(this)
is not working inside a response from an xhr request
I've tried to move .bind(this)
to almost every place I could think but it's still not working
Ultimately I just need to capture this.obj.id
upload(blob8) {
var data = new FormData();
data.append("file", blob8);
var xhr = new XMLHttpRequest();
xhr.withCredentials = true;
xhr.open(
"POST",
"URL"
);
xhr.setRequestHeader("Authorization", `Bearer ${this.state.accessToken}`); //<--- IS WORKING
// xhr.setRequestHeader("Content-Type", "application/octet-stream");
xhr.send(data);
xhr.addEventListener("readystatechange", function() {
if (this.readyState === 4) {
console.log(this.responseText);
this.obj = JSON.parse(this.responseText);
console.log(this.obj);
console.log(this.obj.id);
this.uploadMetaData(this.obj.id).bind(this); // <------- NOT WORKING
} else {
console.log("there is an error here");
}
});
}
Edit:
I missed that the callback is referencing two different this
contexts. Two possible ways to solve this:
upload() {
var that = this;
xhr.addEventListener("readystatechange", function() {
that.uploadMetaData(this.obj.id);
});
}
or
upload() {
var boundUploadMetaData = this.uploadMetaData.bind(this);
xhr.addEventListener("readystatechange", function() {
boundUploadMetaData(this.obj.id);
});
}
Both will call uploadMetaData
with upload()
's this
while allowing the callback to still reference the xhr
object's this
.
Alternatively, I don't think you need to reference the xhr
object's this
at all:
xhr.addEventListener("readystatechange", function() {
if (xhr.readyState === 4) {
var res = JSON.parse(xhr.responseText);
this.uploadMetaData(res.id);
} else {
console.log("there is an error here");
}
}.bind(this));
Original answer:
Assuming this isn't a method for an ES2015 class (it sounds like it isn't if the this
reference in upload()
is correct), the callback for "readystatechange"
will need to be bound to the outer method's (upload()
) this
.
You should be able to do either of the following:
xhr.addEventListener("readystatechange", function() {
// callback body
}.bind(this));
or, if you're able to use ES2015 syntax, then
xhr.addEventListener("readystatechange", () => {
// callback body
});
since arrow function expressions bind this
by their lexical scope.