I'm having problems understanding ngrx (or simply rxjs...), once again.

I have a feature state called "World".
This state has three Actions: Init, InitSuccess and InitFailure.

Also I have other isolated feature states like "Mountains", "Streets", "Rivers".
They have actions like this and corresponding effects to fetch data: Load, LoadSuccess, LoadFailure.

Now I would like to add an effect to WorldActions.Init, which will dispatch Mountains.Load, Streets.Load, Rivers.Load one after another. So ideally an action log would look like this:

1. World.Init
2. Mountains.Load
3. Streets.Load
4. Rivers.Load
5. Mountains.LoadSuccess
6. Streets.LoadSuccess
7. Rivers.LoadSuccess
8. World.InitSuccess

Or when an error occurs:

1. World.Init
2. Mountains.Load
3. Mountains.LoadFailure
4. World.InitFailure

How could an effect pipeline for that look?
How can I dispatch World.InitSuccess only after all LoadSuccess-Actions have happened?
Or am I still trying to implement ngrx in a wrong/bad way?

PS: The reason I am putting everything into separate feature states is because "Mountains" etc. are standalone features on their own. Only in the context of a "World" they belong together. For this reason I can't create a monstrous effect "World.Load", without producing redundant code.

  • 1
    Use something like a an rxjs subject/ behavior subject to manage states.
  • 0
    (((hrmm use unity)))
  • 0
    @bigus-dickus thanks for your reply, I hope I understand correctly: So instead of trying to chain/await external actions/events, I simply subscribe to all the required states within my main effect, merge these subscriptions somehow, and finally dispatch InitSuccess when every required state has e.g. loaded:true?

    Still a bit confused on how to write this in detail, but sounds really good to me. Could you guide me to a snippet where something similar is done?
  • 1
    TLDR: don't try to handle this in a single effect.

    First of all, create the 3 loading effects (takes a Whatever.Load action, calls your service, dispatches Whatever.LoadSuccess or Whatever.LoadFailure accordingly)
    Then, create relaying effects. For instance, one could be Mountains.LoadSuccess -> Streets.Load. Or, if you want to do parallel loading: World.Init -> [Mountains.Load, Streets.Load, Rivers.Load]
  • 1
    @Commodore thanks a lot. My problem is that I don't want to write effects like Mountains.LoadSuccess -> Streets.Load, since they should not depend on each other. Streets should still work, wether or not Mountains are there. I want to be able to reload Mountains without reloading Streets.

    However, parallel loading is what I am trying right now. While this works fine:

    World.Init -> [Mountains.Load, Streets.Load, Rivers.Load]

    I am not sure how to achieve this from a World effect:

    [Mountains.LoadSuccess, Streets.LoadSuccess, Rivers.LoadSuccess] -> World.InitSuccess
  • 1
    The world could subscribe to state changes in Mountains and streets or? If all states are in successful loaded state the world can proceed? 🤔
  • 0
    @Minion was about to suggest something along this line:
    subscribe to all 3 LoadSuccess and check the state each time.

    @sboesch i'm not fond of the sequence either but for accuracy's sake: each load effect will work independantly. What could be bothersome is that firing a Streets.Load would trigger Rivers.Load later on. That could be handled by adding a boolean to your action's payload, enabling/disabling the chain.
  • 0
    I GET THE JOKE. The professor said that for the assignment to develop "Hello World" but you weren't listening and only heard "World".
  • 0
    Use React
  • 0
  • 1
    @bigus-dickus That was actually a joke
  • 0
    @truelion07 doesn't matter, I was bored af.
    Well, haha I guess...
  • 0
    @bigus-dickus this works but this absolutely not the way to go when using ngrx.
Add Comment