Why is 'this' undefined inside class method when using promises?
this
is always the object the method is called on. However, when passing the method to then()
, you are not calling it! The method will be stored somewhere and called from there later. If you want to preserve this
, you will have to do it like this:
.then(() => this.method2())
or if you have to do it the pre-ES6 way, you need to preserve this
before:var that = this;
// ...
.then(function() { that.method2() })
JS class - 'this' is undefined in promise
this
in javascript is weird. Depending on how the code/function is called on the object, it may return values you did not expect. If you are using modern javascript, you should use short arrow notation. This will preserve what this
is binded to. Otherwise, you will have to add .bind(this)
to the function where you are referencing this
:
fetch(path)
.then((response)=>{
return response.json();
}).then((result)=>{
this.place.push({"result":result})
})
Why 'this' is undefined inside a Promise call
:Edit
Wow, the below is kinda true, but the real issue is you didn't initialize state. https://reactjs.org/docs/react-component.html#constructor
constructor() {
super();
this.state = {
coin: {},
hasLoaded: false,
id: ''
}
}
You could use lexical scoping and fix like this, this is a popular pattern to protect this
.Basically, when you use promises or functions from other libraries/ APIs you do not know what they have set their context inside the callback functions to.
In order to use the context you want, you keep the context you need saved in a variable within scope and reference it there _this
, rather than by pointing to the context this
. I'd recommend reading 'you dont know js' to understand this concept further.
componentDidMount() {
console.log('componentDidMount');
const _this = this;
let _id = _this.props.match.params.id.toUpperCase();
if ( _id != _this.state.id.toUpperCase() ) {
axios.get('/data/pricemultifull?fsyms=' + _id + '&tsyms=USD')
.then(response => {
_this.setState({ id: _id }); //this == undefined
});
}
}
The `this` object is undefined when using promise
I am personnaly using bluebird
promises rather then native ES6.
This promises perform faster (https://github.com/petkaantonov/bluebird/tree/master/benchmark), have more convinient API and available in both browsers and node.js (http://bluebirdjs.com/docs/getting-started.html)
I am bind this
value to the first promise in chain - after that your example works well
'use strict';
var Promise = require('bluebird');
class MyClass {
constructor(num) {
this.num = num;
}
start() {
Promise.bind(this)
.then(this._one)
.then(this._two)
.then(this._three)
.then(this._four)
.catch((err) => {
console.log(err.message);
});
}
_one() {
console.log('num: ' + (this.num += 1));
return new Promise((resolve, reject) => {
resolve();
});
}
_two() {
console.log('num: ' + (this.num += 2));
return new Promise((resolve, reject) => {
resolve();
});
}
_three() {
console.log('num: ' + (this.num += 3));
return new Promise((resolve, reject) => {
resolve();
});
}
_four() {
console.log('num: ' + (this.num += 4));
return new Promise((resolve, reject) => {
resolve();
});
}
}
let myClass = new MyClass(4);
myClass.start();
I've also changed methods slightly so that you can see progress in this.num
Why is `this` undefined in a constructor defined Proxy method for a derived class?
You are calling the original function without assigning this
.
Use target.call(thisArg, argumentsList[1])
instead
class Structure {
constructor(name) {
this.noDoors = 0
this.name = name
}
async addDoors(noDoorsToAdd) {
this.noDoors += noDoorsToAdd
console.log(`${noDoorsToAdd} doors added to ${this.name}`)
return new Promise(r => r())
}
}
const Building = class Building extends Structure {
constructor(conditionfunc, args) {
super(args)
this.addDoors = new Proxy(this.addDoors, {
apply(target, thisArg, argumentsList) {
//console.log("apply:",target, thisArg, argumentsList,conditionfunc(argumentsList[0]))
if (conditionfunc(argumentsList[0])) {
console.log(`Correct password: About to add doors to ${thisArg.name}`)
target.call(thisArg, argumentsList[1]);
} else {
console.log(`Incorrect password: Doors not added to ${thisArg.name}`)
}
}
})
}
}
/******** Main Script *********/
let conditionfunc = (password) => {
if (password == '123456') {
return true
} else {
return false
}
}
myStructure = new Structure('Ty Bach')
myBuilding = new Building(conditionfunc, 'Ty Mawr')
;
(async() => {
await myStructure.addDoors(1)
await myBuilding.addDoors('wrongpassword', 7)
await myBuilding.addDoors('123456', 4)
console.log(`${myStructure.name} has ${myStructure.noDoors} doors!`)
console.log(`${myBuilding.name} has ${myBuilding.noDoors} doors!`)
})();
this' is undefined inside a prototype method which use Promise and being called from other prototype method of same object?
The context is lost due to function
, you need to closure it:
isValidDate: function() {
var self = this;
return new Promise( function(resolve, reject) {
console.log(self.startDate);
// ...
});
}
Related Topics
How Do Print the Console Output of the Page in Puppeter as It Would Appear in the Browser
What Is the JavaScript Mime Type for the Type Attribute of a Script Tag
Regular Expression Not Working for at Least One European Character
Prevent JavaScript Keydown Event from Being Handled Multiple Times While Held Down
React 18, Useeffect Is Getting Called Two Times on Mount
Js/Es6: Destructuring of Undefined
How to Use Jquery to Style /Parts/ of All Instances of a Specific Word
JavaScript Es6 Typeerror: Class Constructor Client Cannot Be Invoked Without 'New'
Regular Expression to Match A, Ab, Abc, But Not Ac. ("Starts With")
Set Window to Fullscreen (Real Fullscreen; F11 Functionality) by JavaScript
Rendering to Js with Jinja Produces Invalid Number Rather Than String
When Do I Need to Specify the JavaScript Protocol
JavaScript Closure Not Working
Npm Start Error with Create-React-App
Why Is 'Event' Variable Available Even When Not Passed as a Parameter