How to make synchronous HTTP request in Angular 8 or 9 (make a request and wait)
Solution 1
Demo An asynchronous function is a function that operates asynchronously via the event loop, using an implicit Promise to return its result. But the syntax and structure of your code using async functions are much more like using standard synchronous functions. The await operator is used to wait for a Promise. It can only be used inside an async function.
getDataSynchronous() {
return this.http.get(this.jsonFile).toPromise()
}
in component
async requestDataAndWait() {
let httpData = await this.http.getDataSynchronous();
this.addMessages(httpData)
}
Solution 2
Although is not idiomatic to Angular, you could technically achieve this using a synchronous XHR request:
getDataSynchronous() {
var request = new XMLHttpRequest();
request.open('POST', `${environment.userApiUrl}/logout`, false); // `false`
makes the request synchronous
request.send({});
if (request.status === 200) {
return request.response;
} else {
throw new Error('request failed');
}
}
Note that it cannot be done using Angular HTTP Client, and also that you should not use this solution unless absolutely necessary as synchronous XmlHttpRequest
on the main thread is deprecated in most modern browsers.
Solution 3
This is working for me.
Write this code in your app.component.ts
file:
ngOnInit(): void
{
window.addEventListener('beforeunload', (e) =>
{
this.logoutAndWait();
})
}
async logoutAndWait()
{
const httpData = await this.userService.logoutSynchronous();
}
and create a sync logout function like this below:
logoutSynchronous()
{
return this.http.post<string>(`${environment.userApiUrl}/logout`, {}, { withCredentials: true }).toPromise()
}
Related videos on Youtube
alphanumeric
Updated on July 05, 2022Comments
-
alphanumeric almost 2 years
There are three buttons:
Clicking the first
Request HTTP Data As Promise
button gets its HTTP response as aPromise
.The second
Request HTTP Data As Observable
button gets its response as anObservable
.Both these buttons get their responses using asynchronous response mechanism.
Now, I would like the third
Request HTTP Data and Wait
button to get a synchronous response. I would like it to wait for the http service to return the HTTP response.How could it be done? Here is the link to the Stackblitz project (please use the placeholder function
getDataSynchronous
defined in theHttpService
script to implement this functionality):https://stackblitz.com/edit/angular-ivy-ukgwct?file=src%2Fapp%2Fhttp.service.ts
export class HttpService { jsonFile = '../assets/products.json'; constructor(private http: HttpClient) {} getDataAsPromise(): Promise<any> { return this.http.get(this.jsonFile) .toPromise() } getDataAsObservable(): Observable<any> { return this.http.get(this.jsonFile) } getDataSynchronous(): any { return [] }
-
Phix almost 4 yearsBut why? It blocks the only thread.
-
alphanumeric almost 4 yearsI just want to know how to do it in Angular.
-
-
jonrsharpe almost 4 yearsThere's no point assigning
data
or havingawait
(and thereforeasync
) here - none of that changes the fact thatgetDataSynchronous
is not synchronous, actually returns a promise of the value, and can therefore be implementedgetDataSynchronous() { return this.http.get(this.jsonFile).toPromise() }
. -
jonrsharpe almost 4 years
-
Paulo Pedroso over 3 yearsThanks for the help. I am using a mock to develop offline and I needed to read a file synchrounously in order to do some sorting and filtering.
-
Nate I over 3 yearsI'd like to point out that a blanket statement of "just don't do it" is not conducive to a programming mindset. Think of a front-end app whose api is stateful/headless. You have to send a request to get a CSRF token before many requests. To say "just don't do it" implies that you'd nest all your form requests within a callback -- that's ugly, cumbersome, and generally speaking less maintainable. I can think of more scenarios where a synchronous request is perfectly acceptable as well. Generally, sure, don't take the synchronous shortcut. However, there are cases where it's perfectly fine.
-
Will Taylor over 3 years@NateI your example is not a good one. What if the request takes a long time and the user tries to switch tabs in the browser? What if I want to show an animated loading spinner while the request is in progress? Neither of these things will work, as a synchronous HTTP request will block the browser's UI thread. And if maintainability is a concern we can use
async
/await
for synchronous looking code. IMO it would be a very rare occasion to find a scenario in JavaScript where synchronous HTTP request was the better option. -
Nate I over 3 yearsI mean, this has been discussed thousands of times and is not a mystery by any stretch of the imagination. Calling the synchronous request on a worker will not block the UI thread or cause hitching/freezing, and is essentially the same as
async
/await
. The question asked how to accomplish a synchronous request, andasync
/await
is not synchronous. Neither is a synchronous request on a worker (within the worker it is, so other logic awaiting completion could live there and truly be 'synchronous'), but you asked ;) -
Nate I over 3 yearsThe bottom line is: Provide an answer and an explanation. There's absolutely zero reason to be condescending and dogmatic. Telling anyone "just don't do it" provides zero context and is not helpful in any manner. Had you simply stated in your answer what is listed on the deprecation warning for synchronous requests, you'd have provided actual value instead of a dogmatic, opinionated answer which will be ignored by roughly 99% of devs. The question was how to accomplish a synchronous request, and there are cases out there which call for it (whether you like this fact or not).
-
Will Taylor over 3 years@nate-i fair point, I have reworded the answer.
-
Janos Vinceller almost 3 yearsThis does not make it synchronous. Observables and async methods are not synchronous, so there's no use in trying to interchange them. At the end of the they, you got data if it was successful in some near or later future and you won't if it wasn't. It's a better idea to design your application to be asynchronous and then make use of those asyncronousness.