So, I was trying to get the solution of this problem. But, somehow I am unable to do so, May be because of the lack of knowledge in angular 5. This is my service:
Asynchronous functions cannot be called synchronously, because they are asynchronous.
subscribe
generally shouldn't performed in methods that are expected to be chained. Even if it should, an observable and not a subscription should be returned from a method (a subscription can be additionally saved to be unsubscribed on destruction).
GetCurrentUserInformation
method is redundant because it is just a wrapper for service call. The code can be refactored to:
ngAfterViewInit() {
this.loginService.GetCurrentUserData().subscribe(data => {
this.responseData = data;
if (this.responseData.code != responseCodes.success) {
this.googleInit();
}
});
}
Subscribe to GetCurrentUserData()
the http call is async (every browser api call is async, because the javascript engine runs in a single thread (google for browser event loop for more, this is not an angular issue))
this.GetCurrentUserInformation().subscribe((data: ResponseData) => {
if (this.responseData.code != responseCodes.success) {
this.googleInit();
}
});
this can be simplify by using async/await
there is no direct way to make a synchronous call, however you can do the following procedure (this code is written in angular 7).
import { Component, OnInit } from '@angular/core';
import {HttpClient} from '@angular/common/http';
export class SampleComponent implements OnInit {
Request1result:Object;
Request2result:Object;
constructor(private http:HttpClient) { }
ngOnInit()
{
this.http.get("URL1").subscribe((res)=>{
this.Request1result=res;
this.after1(); // execution will move to next request only when first is done.
});
}
after1()
{
this.http.get("URL2").subscribe((res)=>{
this.Request2result=res;
this.after2(); // execution will move to the rest of the code only when both the requests are done.
});
}
after2()
{
// rest of the code.
console.log(this.Request1result);
console.log(this.Request2result);
}
}
To make sure async calls are executed before processing response you may use Observable.forkJoin() from ReactiveX.
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/observable/forkJoin';
Observable.forkJoin(
this.http.get('/links.json').map((response:Response) => response.json()),
this.http.get('/bookmarks.json').map((response:Response) => response.json())
).subscribe(
data => {
this.links = data[0]
this.bookmarks = data[1]
},
error => console.error(error)
);
subscribe() function's onNext handler will execute when all HTTP requests complete successfully.