wait for asynchronous functions to finish in Angular

So I was working on a new component in Angular and in the ngOninit I have the following asynchronous functions below...

This.getUserProfile needs to be finished before I can call this.getPrivateGroup() and this.getPrivateGroup() needs to be finished before I can call this.loadGroupPosts(). I know I could write these functions inside the callback of the asynchronous requests, but I was wondering if there is a way to keep it in ngOnInit to keep it cleaner?

Anyone has an idea?

ngOnInit() { this.getUserProfile(); // my-workplace depends on a private group and we need to fetch that group and edit // the group data before we proceed and get the group post if (this.isItMyWorkplace) { this.getPrivateGroup(); } this.loadGroupPosts(); } getUserProfile() { this._userService.getUser() .subscribe((res) => { this.user = res.user; console.log('log user', this.user); this.profileImage = res.user['profile_pic']; this.profileImage = this.BASE_URL + `/uploads/${this.profileImage}`; }, (err) => { this.alert.class = 'alert alert-danger'; if (err.status === 401) { this.alert.message = err.error.message; setTimeout(() => { localStorage.clear(); this._router.navigate(['']); }, 3000); } else if (err.status) { this.alert.class = err.error.message; } else { this.alert.message = 'Error! either server is down or no internet connection'; } }); } getPrivateGroup() { console.log('user check', this.user); this.groupService.getPrivateGroup(`${this.user.first_name}${this.user.last_name}`) .subscribe((group) => { console.log('received response', group) }) } // !--LOAD ALL THE GROUP POSTS ON INIT--! // loadGroupPosts() { this.isLoading$.next(true); this.postService.getGroupPosts(this.group_id) .subscribe((res) => { // console.log('Group posts:', res); this.posts = res['posts']; console.log('Group posts:', this.posts); this.isLoading$.next(false); this.show_new_posts_badge = 0; }, (err) => { swal("Error!", "Error while retrieving the posts " + err, "danger"); }); } // !--LOAD ALL THE GROUP POSTS ON INIT--! // 
7

4 Answers

You can use basic promises with async/await.

async ngOnInit() { await this.getUserProfile(); // <-- 1. change // my-workplace depends on a private group and we need to fetch that group and edit // the group data before we proceed and get the group post if (this.isItMyWorkplace) { this.getPrivateGroup(); } this.loadGroupPosts(); } async getUserProfile() { this._userService.getUser() .subscribe((res) => { this.user = res.user; console.log('log user', this.user); this.profileImage = res.user['profile_pic']; this.profileImage = this.BASE_URL + `/uploads/${this.profileImage}`; return true; // <-- this }, (err) => { this.alert.class = 'alert alert-danger'; if (err.status === 401) { this.alert.message = err.error.message; setTimeout(() => { localStorage.clear(); this._router.navigate(['']); }, 3000); } else if (err.status) { this.alert.class = err.error.message; } else { this.alert.message = 'Error! either server is down or no internet connection'; } throw err; }); 

}

4

You could instead leverage RxJS and use a switchMap something like this (syntax NOT checked):

getData(): Observable<string[]> { return this._userService.getUser() .pipe( switchMap(userInfo=> { return this.getPrivateGroup(); }), catchError(this.someErrorHandler) ); } 

One way to do is, return the Observable instead of subscribing in the getPrivateGroup()

getPrivateGroup() { console.log('user check', this.user); return this.groupService.getPrivateGroup(`${this.user.first_name}${this.user.last_name}`) } 

And then, subscribe to the data where you want the chain the this.loadGroupPosts()

 if (this.isItMyWorkplace) { this.getPrivateGroup().subscribe(group => { this.group = group; //you probably want to assign the group data this.loadGroupPosts()}); } 

you could also use the 3rd part of your subscribe function when its completed i am not quite sure if this is a clean solution, in my opinion it is.

ngOnInit() { this.getUserProfile(); } getUserProfile() { this._userService.getUser() .subscribe((res) => { this.user = res.user; console.log('log user', this.user); this.profileImage = res.user['profile_pic']; this.profileImage = this.BASE_URL + `/uploads/${this.profileImage}`; }, (err) => { this.alert.class = 'alert alert-danger'; if (err.status === 401) { this.alert.message = err.error.message; setTimeout(() => { localStorage.clear(); this._router.navigate(['']); }, 3000); } else if (err.status) { this.alert.class = err.error.message; } else { this.alert.message = 'Error! either server is down or no internet connection'; } }, () => { // my-workplace depends on a private group and we need to fetch that group and edit // the group data before we proceed and get the group post if (this.isItMyWorkplace) { this.getPrivateGroup(); } }); } getPrivateGroup() { console.log('user check', this.user); this.groupService.getPrivateGroup(`${this.user.first_name}${this.user.last_name}`) .subscribe((group) => { console.log('received response', group) }, error => { console.log(error) }, () => { this.loadGroupPosts(); }) } loadGroupPosts() { this.isLoading$.next(true); this.postService.getGroupPosts(this.group_id) .subscribe((res) => { // console.log('Group posts:', res); this.posts = res['posts']; console.log('Group posts:', this.posts); this.isLoading$.next(false); this.show_new_posts_badge = 0; }, (err) => { swal("Error!", "Error while retrieving the posts " + err, "danger"); }); } 

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like