Search code examples
angulartypescriptobservable

Angular check conditonal AFTER getting values from subscribe in observable?


Goal: Check IF conditional after getting data from array

What I've tried: I tried looking at a number of other articles on SO that asked about a similar question, but they seemed to be a little different. I need to wait until the entire Array is filled before going to the IF condition

I tried moving the IF condition inside the subscription but it gets called multiple times.

Debugger: Its going from the call to getV() to the method, but when it gets to the first subscribe it goes back to the IF statement.

Typescript:

    ngOnInit {
     this.getV(vId);
     if (this.internalNotes.length > 0) {
              this.dialog.open(DialogInternalNotesThreeComponent, {
                  data: {
                      data: this.internalNotes
                  }
              });
          }
      
    }

    public getV(vId: number) {
        this.vs.V(vId)
            .subscribe(resp => {
                this.ps.GetPInternalNotes(resp.PID.toString()).subscribe(respPIN => {
                    for (let index = 0; index < respPIN.length; index++) {
                        this.internalNotes.push(respPIN[index]);
                        
                    }
                });
            });         
    }

EDIT: Putting it immediately after the FOR statement in the subscribe seems to resolve the multiple dialogs. Does this look correct?

public getV(vId: number) {
        this.vs.V(vId)
            .subscribe(resp => {
                this.ps.GetPInternalNotes(resp.PID.toString()).subscribe(respPIN => {
                    for (let index = 0; index < respPIN.length; index++) {
                        this.internalNotes.push(respPIN[index]);
                    }
                    if (this.internalNotes.length > 0) {
                        this.dialog.open(DialogInternalNotesThreeComponent, {
                            data: {
                                data: this.internalNotes
                            }
                        });
                    }
                });
            });         
    }

Solution

  • I think you misunderstand observables, you expect this code to run sync (aka line by line) but this is not the essence of reactive programming.

    this.getV(vId);
    if (this.internalNotes.length > 0)
    

    by reaching the if the array is not necessarily initialized since we might reach this line while the observable did not push respPIN[index] to the array yet.

    that's why Putting it immediately after the FOR statement in the subscribe seems to resolve the multiple dialogs works.

    if you want to keep your behaviour you want to return an observable of that array inside your getV()

    ngOnInit {
      // subscribe to the returned array
      this.getV(vId).subscribe(
           (internalNotes) => {
                if (internalNotes.length > 0) {
                    this.dialog.open(DialogInternalNotesThreeComponent, {
                        data: {
                            data: internalNotes
                        }
                    });
                  }
            });
     }
    
     // method returns an observable with your array
     public getV(vId: number): Observable<Array<any>> {
         this.vs.V(vId)
             .subscribe(resp => {
                 this.ps.GetPInternalNotes(resp.PID.toString()).subscribe(respPIN => {
                     for (let index = 0; index < respPIN.length; index++) {
                         this.internalNotes.push(respPIN[index]); 
                     }
                     // return an observable with your current array
                     return of(this.internalNotes);
                 });
             });
    
        // base case return an empty observable  
        return EMPTY;       
     }