Neamesis
Neamesis

Reputation: 744

Angular (observable): update interval in merge

I'm wondering how to change the interval value in my merge when I update my data in my table :

 merge(this.sort.sortChange, this.paginator.page, interval(this.delay))
      .pipe(
        startWith({}), // ... fetch data

I need the table isn't update while the dialog is open when I click on a row, so I'd like to put a big timer in the interval (or if you have a better solution, or if you know to obtain the max date in TS it's welcome too ^^')

  selectRow(row: GithubIssue) {
    this.selection.select(row);
    this.delay = 10000000;

    const dialogRef = this.dialog.open(DialogComponent);
      dialogRef.afterClosed().subscribe(() => {
        this.selection.clear();
        this.delay = 30000;
      });
  }

I've made a stackblitz repo if it can help : repo stackblitz

Thanks for your help

Upvotes: 0

Views: 176

Answers (2)

Mrk Sef
Mrk Sef

Reputation: 8022

You can make an interval stream that can be toggled on and off via a toggle subject. Let's say there's keepUpdating$ = new BehaviorSubject<boolean>(true); in the global scope.

toggleInterval$ = keepUpdating$.pipe(
  switchMap(update =>
    update? interval(this.delay) : EMPTY
  )
);

merge(this.sort.sortChange, this.paginator.page, toggleInterval$)
  .pipe(
    startWith({}), // ... fetch data

and then you can use it like this:

selectRow(row: GithubIssue) {
  this.selection.select(row);
  this.keepUpdating$.next(false);

  const dialogRef = this.dialog.open(DialogComponent);
    dialogRef.afterClosed().subscribe(() => {
      this.selection.clear();
      this.keepUpdating$.next(true);
    });
 }

Side note:

It's probably a bad design choice to poll your backend/database like this. If you want to update your table in realtime, it's a bad user-experience to have your table hiccup (with a loading animation) while waiting for any update. Instead, you should consider performing the update in the background and pushing the update to the table once it's ready to display.

Then there is no need for an interval to check, you just push changes as they're ready.

Upvotes: 1

MoxxiManagarm
MoxxiManagarm

Reputation: 9124

I would try it with the skipWhile operator. Something like

.pipe(
  skipWhile(() => this.dialogRef && this.dialogRef.getState() === MatDialogState.OPEN)
)

Upvotes: 0

Related Questions