TS Code:
var APIres: any;
export class Component implements OnInit {
async getInfo(){
await this.apicall();
console.log('API response', APIres)
}
async apicall(){
var request = new XMLHttpRequest();
request.open('POST', 'URL', true);
request.setRequestHeader('Content-Type', 'application/json');
request.setRequestHeader('Authorization', 'Bearer ' accessToken);
request.onreadystatechange = async function () {
console.log('Got Values')
await res(JSON.parse(this.responseText));
}
request.send(content);
}
}
async function res(x){console.log('out');APIres = x} //Outside of export
Output:
API response undefined
Got Values
out
Desire Output:
Got Values
out
API response res
CodePudding user response:
Adding async
doesn't magically cause the function to wait for an event
Wrap your function with a promise
var APIres: any;
export class Component implements OnInit {
async getInfo() {
await this.apicall();
console.log("API response", APIres);
}
apicall() {
return new Promise((resolve) => {
var request = new XMLHttpRequest();
request.open("POST", "URL", true);
request.setRequestHeader("Content-Type", "application/json");
request.setRequestHeader("Authorization", "Bearer " accessToken);
request.onreadystatechange = function () {
console.log("Got Values");
resolve(res(JSON.parse(this.responseText)));
};
request.send(content);
});
}
}
async function res(x) {
console.log("out");
APIres = x;
} //Outside of export
CodePudding user response:
Nothing in the code connects the completion of the XHR call with the promise that apicall
returns. Although you could wrap XHR in a promise, it makes more sense to use the modern replacement, fetch
.
Separately, as VLAZ pointed out in a comment, it's poor practice to populate global data as a side-effect of a method call. Instead, have the methods return the necessary data.
Here's an example using fetch
:
export class Component implements OnInit {
async getInfo() {
// Note receiving the data as the return value of the method
const apiData = await this.apicall();
console.log("API response", apiData);
return apiData; // Provide the data to the caller
}
async apicall() {
// `fetch` returns a promise of a Response object
const response = await fetch("/url/here", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: "Bearer " accessToken,
},
body: content,
});
// If the response wasn't okay...
if (!response.ok) {
// ...fail with an error
throw new Error(`HTTP error ${response.status}`);
}
// The response was okay, read and parse the JSON
return await response.json();
}
}