2

I have the following code block in my ngOnInit as below:

this.subscriptions = this.formService.getFormFromApi(this.formId)
      .pipe(
        concatMap(theForm => this.formService.getFormStructure(theForm))
      ).pipe(
        take(1),
        tap(tree => { this.treeNodeData = tree; }),
        (finalize(() => this.isTreeLoading = false))
      ).subscribe();
...
    this.subscriptions.add(
      combineLatest(
        this.fileService.getFiles(this.formId),        
        this.formService.questionsList
      ).pipe(
        tap(arrResult => {
          this.fileData = arrResult[0];          
          this.test = arrResult[1];
          console.log("fired.")
        })
      ).subscribe()
    );
...

The idea is as below:
When the column definition changes as determined by the questionsList, I wish to re-render the the table. I plan to do this by getting the files again (Don't worry about calling http repeatedly. When this works, I will replace the logic with something more efficient)

However, even when the BehaviorSubject is changing values (columns to display in table) all the time, the result does not get refreshed. Basically, "fired" does not run after the first time when the page loads.

Why is this happening? Is it because the http call has completed and the questionsList has not? I had the notion that combineLatest will fire as long as one of the observables emit something?

clami219
  • 2,958
  • 1
  • 31
  • 45
Han K
  • 105
  • 2
  • 9
  • Could you create a stackblitz project – prabhatojha Feb 13 '20 at 03:38
  • @prabhatojha here's the stackblitz: [link](https://stackblitz.com/edit/angular-vhrumy) But I've only now found out why it was not working through setting up my stackblitz. FYI in the stackblitz, everything fires and work as expected. – Han K Feb 13 '20 at 04:03

1 Answers1

1

I have resolved this. After removing the this.subscriptions.add() it works as expected.

// this.subscriptions.add(
      combineLatest(
        this.fileService.getFiles(this.formId),        
        this.formService.questionsList
      ).pipe(
        tap(arrResult => {
          this.fileData = arrResult[0];          
          this.test = arrResult[1];
          console.log("fired.")
        })
      ).subscribe()
   // );

If some rxjs guru could explain this phenomenon, please add or edit this answer.

Han K
  • 105
  • 2
  • 9
  • This solution doesn't seem consistent with your original problem. My suggestion would've been to set up your subscription such that any emissions on `questionsList` are piped through to `getFiles()`, like: `this.formService.questionsList.pipe(switchMap(() => this.fileService.getFiles(...)), ...)`. In this way, you're stating that `getFiles()` will be retriggered every time `questionsList` changes. – miqh Feb 13 '20 at 04:20
  • @miqh I agree with you. I was more glad that the ````combineLatest```` was actually working as what the documentation and what my prior knowledge suggests. So what you suggest is that, to avoid this problem altogether, trigger ````getFiles()```` upon EVERY emit of ````questionsList```` ````BehaviorSubject````. This would mean doing away with the need for ````combineLatest```` completely? – Han K Feb 13 '20 at 04:26
  • 1
    Yup, exactly—you wouldn't need `combineLatest` at all because of the emission relationship set up by the pipe on `questionsList`. – miqh Feb 13 '20 at 04:55
  • @miqh cheers, mate. a fresh set of eyes always brings about improvements. – Han K Feb 13 '20 at 04:58
  • 1
    Thank you, thanks to you I understanded what is the problem. When you add to a Subscription an Observable that already exists and finshed on the Subscription - it won't add it actually... – A K Mar 14 '21 at 00:11