The functions look like running in parallel because they have Observables inside it, so they run asynchronously. You can find some explanation about asynchronous and synchronous functions here.
In short, in a synchronous code, a task needs to be finished before moving the another one, while in asynchronous code, your running code can move to another task before the execution of a task has ended.
To guarantee that a task B will be executed after an asynchronous task A, you need to explicitly indicate that B will be executed after task A has finished.
When you subscribe to a task, the code inside the subscribe method will be executed after the conclusion of the respective task.
So, one way to accomplish your goal is returning an Observable in both getUserInfo()
and getUserFeed()
functions. After that, on ngOnInit() you can call getUserFeed()
inside the subscribe block of getUserInfo()
:
ngOnInit(): void {
this.getUserInfo().subscribe(
(response: any) => {
this.userId = response.id;
// getUserFeed() called inside the subscribe block
this.getUserFeed().subscribe(
(response: any) => {
this.post = response.data.posts.data;
}
);
}
);
}
public getUserInfo() {
return this.userFeedService.getShowdaUserInfo();
}
public getUserFeed() {
return this.userFeedService.getShowdaUserFeed(this.params, this.userId);
}
This approach is just to understand that if your logic needs some asynchronous tasks to be executed in some order, so you need to chain them. But, as apponted by Yuriy, it is not a good practice. A better way is to use rxjs methods like switchMap
or mergeMap
, like Yuriy also did, which is a bit more advanced:
ngOnInit(): void {
this.getUserInfo()
.pipe(switchMap((response: any) => this.getUserFeed(response.id))
.subscribe((response: any) => this.post = response.data.posts.data))
}
public getUserInfo() {
return this.userFeedService.getShowdaUserInfo();
}
public getUserFeed(id: any) {
return this.userFeedService.getShowdaUserFeed(this.params, id);
}
P.S. If you are not familiar with rxjs library, switchMap
is a rxjs Pipeable Operator. A Pipeable Operator is an operator called using a syntax like observable1.pipe(operator())
. A Pipeable Operator doesn't change the original observable, but return a new one after some transformation based on the first one. More details at the Rxjs page.