Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use await/async in ngOnInit?

I am trying to call a function in the ngOnInit() and feed it two values. So this is the function I'm trying to call inside the ngOnInit: this.complexWordIdentification(this.postIWant, this.theHardWords);

The issue here is that this.postIWant and this.theHardWords are getting resolved in the ngOnInit itself as you can see below, which is causing the error. Now how can I call the this.complexWordIdentification(this.postIWant, this.theHardWords); and feed it those values without getting an error?

I have been thinking about the await functions? But I can not figure it out, any advice on this, please?

This is my ngOnInit:

ngOnInit() {
    this.isLoading = true;
    this.wordsLoaded = false;
    this.postLoaded = false;
    this.form = new FormGroup({
      annotation: new FormControl(null, {
        validators: [
          Validators.required,
          Validators.minLength(8),
          Validators.maxLength(250)
        ]
      })
    });
    this.id = this.route.snapshot.paramMap.get('postId');
    this.annotationService.getWords();
    this.annotationSub = this.annotationService
      .getWordUpdateListener()
      .subscribe((thewords: ComplexWord[]) => {
        this.thewords = thewords;
        this.thewords.map(word => {
          this.theHardWords.push(word.word);
          this.wordWithAnnotation.push(word);
        });
        this.wordsLoaded = true;
        this.isLoading = this.postLoaded && this.wordsLoaded;
      });
    this.postsService.getPosts();
    this.postsSub = this.postsService
      .getPostUpdateListener()
      .subscribe((posts: Post[]) => {
        this.posts = posts;
        this.posts.map(post => {
          if (post.id === this.id) {
            this.postIWant = post.fileText;
          }
        });
        this.postLoaded = true;
        this.isLoading = !(this.postLoaded && this.wordsLoaded);
      });
    this.role = this.authService.getUserRole();
    this.userIsAuthenticated = this.authService.getIsAuth();
    this.authStatus = this.authService
      .getAuthStatus()
      .subscribe(isAuthenticated => {
        this.userIsAuthenticated = isAuthenticated;
        this.role = this.authService.getUserRole();
      });
}

If anyone can point me in the right direction it would be great, as I am not too experienced in this field. Currently I am having to call this.complexWordIdentification(this.postIWant, this.theHardWords); outside of the ngOnInit to avoid the error but obviously, I would like to call it automatically.

like image 210
Andrew Avatar asked Jan 28 '23 18:01

Andrew


1 Answers

forkJoin combines the two subscriptions into a single one and returns an array of their results. It is extremely useful to use in ngOnInit when you need data from multiple sources before you can finish loading the component.

https://www.learnrxjs.io/operators/combination/forkjoin.html

import { Observable } from "rxjs/Observable";
    Observable.forkJoin(
        this.annotationService.getWordUpdateListener(),
        this.postsService.getPostUpdateListener()
    ).subscribe((data) => {
         // data[0] result from getWordUpdateListener
         this.thewords = data[0];
            this.thewords.map(word => {
              this.theHardWords.push(word.word);
              this.wordWithAnnotation.push(word);
            });
            this.wordsLoaded = true;

         // data[1] result from getPostUpdateListener
         this.posts.map(post => {
              if (post.id === this.id) {
                this.postIWant = post.fileText;
              }
            });
            this.postLoaded = true;
        this.isLoading = false;
        this.complexWordIdentification(this.postIWant, this.theHardWords);
    }, (err) => {
        // error handling
    });

edit:added Import Statement for Observable in RXJS 5 and below

Edit: RXJS 6 update, changes import statment

import { forkJoin} from 'rxjs';
forkJoin(this.annotationService.getWordUpdateListener(),
            this.postsService.getPostUpdateListener()
).subscribe((data) => { \\do stuff}, (err) => { \\ do error stuff}

Edit 2: RXJS changed the signature of forkJoin it now takes an array

    forkJoin([this.annotationService.getWordUpdateListener(),
            this.postsService.getPostUpdateListener()]
).subscribe((data) => { \\do stuff}, (err) => { \\ do error stuff}
like image 153
Calidus Avatar answered Jan 31 '23 22:01

Calidus