18

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
    post the code of each function Commented Dec 17, 2018 at 14:53
  • How getPrivateGroup function looks like? Commented Dec 17, 2018 at 14:53
  • Ok, I'll post it Commented Dec 17, 2018 at 15:01
  • Added the functions. Commented Dec 17, 2018 at 15:04
  • Unless you menction them with @ they won't get notified Commented Dec 17, 2018 at 15:06

4 Answers 4

24

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;
      });

}

Sign up to request clarification or add additional context in comments.

4 Comments

Thank you for your response. Is it possible I would have to add async next to ngOninit for it to work?
Yes totally - forgot about that, sorry.
Great, I'll test it out and let you know if it worked
Check the edited answer - I think it should also work with a proper async function. Not sure if you know it: by returning something out of async functions we resolve the promise it creates (which is awaited in the ngOnInit).
5

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)
    );
}

Comments

1

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()});
        }

Comments

0

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");
    });
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.