Why Is 'This' Undefined Inside Class Method When Using Promises

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



Leave a reply



Submit