Issue
I would like to show a list of posts like this: Post List
To show which post is favorized by a user I need data from two different collections out of my mongodb database. Currently the ngOnInit of my post-list.component.ts file looks like this:
ngOnInit() {
this.isLoading = true;
this.postsService.getPosts(this.postsPerPage, this.currentPage);
this.favoritesService.getFavorites(this.postsPerPage, this.currentPage);
this.userId = this.authService.getUserId();
this.postsSub = this.postsService
.getPostUpdateListener()
.subscribe((postData: { posts: Post[]; postCount: number }) => {
this.totalPosts = postData.postCount;
this.posts = postData.posts;
console.log("Posts fetched successful!");
});
this.favoritesSub = this.favoritesService
.getFavoriteUpdateListener()
.subscribe(
(favoriteData: { favorites: Favorite[]; postCount: number }) => {
this.isLoading = false;
this.favorites = favoriteData.favorites;
this.fetchFavorites();
console.log("Favorites fetched successful!");
}
);
this.userIsAuthenticated = this.authService.getIsAuth();
this.authStatusSub = this.authService
.getAuthStatusListener()
.subscribe((isAuthenticated) => {
this.userIsAuthenticated = isAuthenticated;
this.userId = this.authService.getUserId();
});
}
Is there any possibility to first await the post data to arrive?
Solution
You have several options to achieve your wanted behavior.
Option 1:
You can use the RxJS operator switchMap which becomes executed as soon as the subscription emits and returns a new Observable. See here for more infos about switchMap ;)
I'm using your calls getPostUpdateListener and getFavoriteUpdateListener as example, so it would look something like this:
...
this.postsSub = this.postsService
.getPostUpdateListener()
.pipe(
switchMap((postData: { posts: Post[]; postCount: number }) => {
this.totalPosts = postData.postCount;
this.posts = postData.posts;
console.log("Posts fetched successful!");
return this.favoritesService.getFavoriteUpdateListener();
})
)
.subscribe((favoriteData: { favorites: Favorite[]; postCount: number }) => {
this.isLoading = false;
this.favorites = favoriteData.favorites;
this.fetchFavorites();
console.log("Favorites fetched successful!");
});
...
Option 2:
You can promisify your Observable with firstValueFrom or lastValueFrom and then you can wait for it's execution, e.g. with async/await. See here for more information ;)
This would look like following:
async ngOnInit() {
...
const postData: { posts: Post[]; postCount: number } = await firstValueFrom(this.postsService.getPostUpdateListener());
this.totalPosts = postData.postCount;
this.posts = postData.posts;
console.log("Posts fetched successful!");
const favoriteData: { favorites: Favorite[]; postCount: number } = await firstValueFrom(this.favoritesService.getFavoriteUpdateListener());
this.isLoading = false;
this.favorites = favoriteData.favorites;
this.fetchFavorites();
console.log("Favorites fetched successful!");
...
}
Since Angular is working a lot in the reactive way I'd go with option 1 ;)
Answered By - Batajus
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.