NgRx effects and conditionals

Ohoy everyone, I posted a question on a local slack workspace and Lars Brink suggested I made a post on here to get more feedback or a discussion going. So here we go:

We got a fairly large Angular application that uses NgRx across a set of lazy loaded modules (services in our context, or mini applications if you will).
Each service will, upon being routed to, load its own initial data. This can range from 1 to several requests depending on where data comes from.

Currently we load data via @ngrx/effects by listening to the router and filtering on routes, so something like;

navigation = createEffect(() => this.actions$.pipe(
    // switchMap into service, load data > normal effects flow

the ofRoute operator works with the @ngrx/router-store as a filter much like ofType for Actions. So far so good.

Now, we have the option of giving the users a guided tour through the service, and in order to do so, we might need to load in some mocked data for us to show the tour properly.
We use a lib for the tour itself that takes a set of steps and hooks up to anchors (directives) so we know where to show the tour popover content.
My issue is this whole mock-data load thing;

  1. Route to application
    2a. If application has tour, and user hasn´t seen it, kick it off
    2b. If the user already has seen the tour, we proceed as normal

The issue here is, I sort of need to let every effect that kicks off during service init, know of a boolean (isTourActive). In order to block further execution of those effects.

It just sort of feels… messy. I mean it works! And there is no doubt that we need a way for the normal flow to not run when a tour is being initiated.

I´ve been proposing setting aside some time to improve upon the tour implementation, as there is a lot of duplicate code among services that has a tour.

I am not allowed to post our real code 1:1, but i´ll happily provide more context if needed.

Things i´ve thought about already:

  • Injecting effects during runtime using injectionTokens (This is an upcoming addition to NgRx, currently a pull request
  • Handling the tour data via interceptors, to sort of let the normal effect flow stay unaffected, but the data loaded would be mock data based on isActiveTour via the interceptor. This requires a little more setup, as the interceptor would live in the root, and depending on the active feature module, have the configuration (which endpoints to mock) be loaded
  • I actually just noticed OnRunEffects from docs and maybe that could be a thing?

I might be overthinking this, but I haven´t found a good solution.
Our current solution works, but is messy. The good part is that our components aren´t touched, so they´re still easily testable, but the effects flow behind the scenes is… messy as said before.

I hope someone might have a good idea or can point me in the right direction. I might not have tons of hours available as we are loaded on feature tasks for the next couple of months, but if it´s worth doing and makes our lives easier, i´ll get it done.

_ps. Also my first time posting in here, so hi everyone!


1 Like

After tips from Tim on twitter, I went with OnRunEffects to switch between the mockEffects and the realEffects.

So far it´s working wonderfully!

1 Like