angular-plugins icon indicating copy to clipboard operation
angular-plugins copied to clipboard

[entity-component-store] `all$` emits `undefined[]`

Open LayZeeDK opened this issue 2 years ago • 2 comments

Minimal reproduction of the bug/regression with instructions:

  1. Create an entity component store
  2. Subscribe to EntityComponentStore#all$
  3. Activate an async effect like a network request that adds entitites by using EntityComponentStore#addMany or another add method
  4. EntityComponentStore#all$ unexpectedly emits [undefined x <number of entities>]
  5. EntityComponentStore#all$ emits the expected entities

Expected behavior:

EntityComponentStore#all$ shouldn't emit undefined[].

Versions of RxMind, NgRx, Angular, Node, affected browser(s) and operating system(s):

I tried the following configurations locally and in StackBlitz

Angular NgRx ComponentStore RxMind Entity Component Store OS Browser Reproduction
16.2 16.2 14.0 Windows 11 Pro Microsoft Edge 116.0.1938.62 (64-bit)
Google Chrome 116.0.5845.141 (64-bit)
StackBlitz
14.3 14.3 14.0 Windows 11 Pro Microsoft Edge 116.0.1938.62 (64-bit)
Google Chrome 116.0.5845.141 (64-bit)
StackBlitz

Other information:

When EntityComponentStore#addMany or another add method is called from a regular (non-effect) method or from the class constructor, the issue doesn't occur.

In the reproductions, I use the asyncScheduler to simulate an HTTP response but when the effect is synchronous, the issue also occurs.

When adding for example two entities, EntityComponentStore#all$ emits [undefined, undefined].

I would be willing to submit a PR to fix this issue

[x] Yes (Assistance is provided if you need help submitting a pull request) [ ] No

LayZeeDK avatar Aug 31 '23 12:08 LayZeeDK

@markostanimirovic says that it looks like state.entities are added in a different VM turn than state.ids.

LayZeeDK avatar Sep 01 '23 04:09 LayZeeDK

@markostanimirovic

Would it be okay to add { debounce: true } to the all$ selector? It seems to fix this issue,

all$ = this.select(
  this.select(
    {
      ids: this.ids$,
      entities: this.entities$,
    },
    {
      debounce: true,
    }
  ),
  ({ ids, entities }) => ids.map(id => entities[id])
);

LayZeeDK avatar Sep 15 '23 08:09 LayZeeDK