vendredi 31 août 2018

How to choose from Observable or regular value

I've been confusing with Observable since getting started with Angular (not AngularJS) and rxjs.

Observable is convenient and provided a FP way of organizing information. However it becomes very cumbersome when mixed with regular values.

For example, suppose we have a data table, in which each row has a checkbox and there is a "select all" checkbox in the header row. A very common use case.

The data source of the data table is an Observable. So the pseudo-code will be like:

// sample.component.ts, suppose data source comes from ngrx store
rows$ = this.store.pipe(select(selectRows)); 
// sample.component.html
<table [dataSource]="rows$">

With this setup, we can implement the check box for each data row as follow, storing the on/off status in local state:

// sample.component.ts
state = { selection: {} };
handleSelect(id, event) {
    this.state.selection[id] = event.checked;
}

Now here are the problems:

  1. In order to calculate the "all selected or not" state, I need to know both rows$ and this.state.selection so that I can tell whether all rows are selected or not. However rows$ is an Observable while this.state.seletion is a regular object. My options are:

    a) Convert this.state.selection into an Observable by creating an rxjs.Subject and update its value in each handleSelect() event handler, then merge this new Observable with rows$ to compute the "all selected" state

    b) Subscribe rows$ and convert it to a regular array rows, then compute the all selected state in handleSelect()

  2. When user clicks the "select all" checkbox, I need to update this.state.selection to assign all ids to true or false. Again all the ids have to be retrieved from rows$, which is an Observable. So there are two options as well:

    a) Convert "select all" event to an Observable, then merge it with rows$ and update this.state.selection as a side effect

    b) The same as 1.b), subscribe rows$ to rows and do the calculation in handleSelectAll() handler

For me it looks like the easiest way is to first convert rows$ to rows and DON'T use Observable at all in the component. Because in order to use Observable I need to convert everything else (state, events, ...) into Observable.

But if I am correct, why ngrx provides Observable interface only?

So I believe I'm thinking soemthing wrong.

I appreciate if anyone could share some light on this.

Aucun commentaire:

Enregistrer un commentaire