Reputation: 159
My code looks like this:
public getUrl(url) {
//returns URL
... }
public getResponseFromURL(): container {
let myStatus = 4;
const abc = http.get(url, (respon) =>
const { statusCode } = respon;
myStatus = statusCode;
console.log('Inside callback' +myStatus);
.on('error', (err) => {
console.log('Things have gone wrong' + err);
});
console.log('ITS COMPLICATED' +myStatus);
return new Container(status, body, header);
}
}
The problem I am facing is because of the asynchronous nature of JS and the console.log('ITS COMPLICATED') gets executed before the one in the callback function. I am trying to have the first one executed before the last console.log!
I am using Async/Await like below:
public timeoutPromise(time: any) {
return new Promise((resolve) => {
setTimeout(() => {
resolve(Date.now());
}, time);
});
}
public doSomethingAsync() {
return this.timeoutPromise(1000);
}
As a result changed my getResponseFromURL() to:
public async getResponseFromURL(): Promise<container> {
this.myStatus = 7;
console.log(0);
await this.doSomethingAsync();
console.log(1);
const abc = http.get(url, (respon) => {
const { statusCode } = respon;
this.myStatus = statusCode;
console.log('Inside Callback ' + statusCode);
}).on('error', (err) => {
console.log('Things have gone wrong ' + err);
});
await this.doSomethingAsync();
console.log(2);
await this.doSomethingAsync();
console.log('Is it simple lalala ' + this.myStatus);
await this.doSomethingAsync();
}
}
The problem with doing this was if my container class (return type of getResponseFromURL()) is a container for status and body when I am testing this async function, before expect.getResponseFromURL().getStatus().toBe(200)
would work.
Test looks like below:
test('Async function', async () => {
expect.assertions(1);
const data = await ContainerGlobals.getResponseFromURL().getStatus();
expect(data).toBe(207);
});
Now I am getting error from .getStatus()
and I am not sure how to bypass this error?
"does not exist on Promise"
Upvotes: 7
Views: 30923
Reputation: 45850
In the code above await
is called on the result of calling getStatus
on the result of calling ContainerGlobals.getResponseFromURL()
.
ContainerGlobals.getResponseFromURL()
returns a Promise
and immediately calling getStatus()
on the Promise
gives an error since getStatus
"does not exist on Promise
".
await
needs to be called on the Promise
returned by ContainerGlobals.getResponseFromURL()
, and getStatus
should be called on the result returned by await
.
The quickest way to fix this is to throw parenthesis around the await
:
test('Async function', async () => {
expect.assertions(1);
const data = (await ContainerGlobals.getResponseFromURL()).getStatus();
expect(data).toBe(207); // SUCCESS
});
...but you might want to split the await
line into two lines for readability:
test('Async function', async () => {
expect.assertions(1);
const result = await ContainerGlobals.getResponseFromURL(); // let the Promise resolve
const data = result.getStatus(); // call getStatus on the result
expect(data).toBe(207); // SUCCESS
});
Upvotes: 5