I am developing a NodeJS package that contains a Thenable class (see Thenable objects) that is supposed to return this
(the initialized object itself), but instead it is returning a new, uninitialized object and it is stuck in a neverending loop. Below is the code:
node_modules/<my package>/index.js
const axios = require('axios');
const config = require('./config.json');
class MyAPI {
#token = "";
constructor(username, password) {
this.#token = token;
}
then(resolve, reject) {
const options = {
url: "/api/authenticate",
baseURL: "https://myapi.com/",
method: 'post',
maxRedirects: 0,
data: {
token: this.#token
},
transformRequest: this.#transformRequest('urlencoded'),
transformResponse: this.#transformResponse
};
axios.request(options).then((res) => {
if (res.data.authenticated === true) {
console.log("Authenticated!");
resolve(this); // <-- should return the initialized object, but instead returns a new uninitialized object
} else {
reject(new Error('Invalid credentials'));
}
});
}
#transformRequest(type) {
if (type === 'urlencoded') {
return function(data) {
return (new URLSearchParams(data)).toString();
}
} else if (type === 'json') {
return function(data) {
return JSON.stringify(data);
}
}
}
#transformResponse(data) {
return JSON.parse(data);
}
getSomething() {
// Gets something from remote API
return response;
}
}
module.exports.MyAPI = MyAPI;
index.js
const { MyAPI } = require('<my package>');
(async function(){
try {
const app = await new MyAPI(config.auth.token);
console.log("App initialized!"); // Code never reaches this command
console.log(app.getSomething());
} catch (e) {...} // Handle the error
})()
The log gets filled up with "Authenticated!" and the code never makes it to console.log("App initialized!")
. I've seen this answer but it does not help me because I know this
is referring correctly to the object.
Replacing resolve(this)
with resolve()
stops this, but await new MyAPI()
resolves to undefined
and I cannot later run app.getSomething()
.
In a non-Thenable class (e.g. new MyClass()
), it resolves to the object itself, so further operations can be done on it, so why can't await new MyAPI()
also resolve to the object itself like a constructor should?