The following code works fine:
useEffect(() => {
const apiService = new APIClient('api address');
var topicCommentsReq = new GetTopicDetailsRequest();
topicCommentsReq.setTopicCid(Buffer.from("123", "hex"));
apiService.getTopicDetails(topicCommentsReq, {}, function (err, response) {
console.log(`response : ${JSON.stringify(response)}`);
});
}
I want to convert this callback style function to async/await style, so i did something like this:
const promisifyFn =
(fn: Function) =>
(...args: any[]) =>
new Promise((resolve, reject) => {
return fn(...args, (err: Error, data: any) => {
return err ? reject(err) : resolve(data);
});
});
useEffect(() => {
(async () => {
const apiService = new APIClient("api address");
const topicCommentsReq = new GetTopicDetailsRequest();
topicCommentsReq.setTopicCid(Buffer.from("123", "hex"));
const getTopicDetails = promisifyFn(apiService.getTopicDetails);
try {
const res = await getTopicDetails(topicCommentsReq, {});
console.log(`response : ${JSON.stringify(res)}`);
} catch (e) {
console.log(e);
}
})();
});
The following error message shows up:
TypeError: Cannot read properties of undefined (reading 'client_')
if (callback !== undefined) {
return this.client_.rpcCall(
this.hostname_
'/StelaPlatform.GRPC.API/GetTopicDetails',
request,
metadata || {},
this.methodDescriptorGetTopicDetails,
callback);
}
My guess is this problem related with the lcoal scope. When the function run inside async function, the this scope is different. But how should I resolve this issue in general?
CodePudding user response:
The problem is in passing the function reference to apiService.getTopicDetails
, it loses its this
context.
In order to keep the prototype function in its prototype, you should use either an arrow function...
const getTopicDetails = promisifyFn((...args) =>
apiService.getTopicDetails(...args));
const getTopicDetails = promisifyFn(apiService.getTopicDetails.bind(apiService));