Platform: Effects generated by Schematics cause 100% CPU / Frozen tab

Created on 24 Jan 2019  路  8Comments  路  Source: ngrx/platform

Minimal reproduction of the bug/regression with instructions:

  1. Run ng generate @ngrx/schematics:feature
  2. Start the server
  3. Open page
  4. Observe browser freeze

This is because in the generated module the generated action is dispatched. The effects listen for that dispatched action however does not filter the action so it gets dispatched as a result of passing through the effects.

Expected behavior:

Dispatch loop does not occur.

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

"@angular/core": "7.2.2",
"@ngrx/effects": "7.0.0",
"@ngrx/router-store": "^7.0.0",
"@ngrx/store": "7.0.0",
"@ngrx/store-devtools": "7.0.0",
Node v10  

Other information:

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

Schematics

Most helpful comment

I used the @Effect{dispatch: false} method.

An alternative is to add a second action FooLoaded and have the effect mapTo(new FooLoaded()) to show that the all the feature components are registered and working.

However, I'm open for whatever is clear and fixes the behavior.

All 8 comments

Hi @adamduren I am attempting to recreate this issue and so far haven't had any luck. Here's what I have done.

  1. Generated new app with ng new test-app
  2. Installed ngrx dependencies
  3. Setup schematics
  4. Ran ng generate @ngrx/schematics:store State --root --module app.module.ts
  5. Ran ng generate feature User --group --reducers reducers/index.ts
  6. Injected the store into the app.component.ts class file
  7. Added the following to ngOnInit
ngOnInit() {
    this.store$.pipe(select(s => console.log('User', s.user)));
    this.store$.dispatch(new LoadUsers());
}

Are you doing something differently?
Thanks!

My guess is that the schematic generates the effect:

@Effect()
loadFoos$ = this.actions$.pipe(ofType(FoosActionTypes.LoadFoos));

Which causes the famous infinite loop 鈽狅笍 .

In order to fix this I think we can:

1) create the effect as @Effect({dispatch:false})
2) don't generate the effect
3) add some more logic to the effect

But I think all these options make it more complicated for our users 馃

Can confirm.... Adding UserEffects to the EffectsModule.forRoot([]) causes the behavior described.

I vote for creating the effect class with the constructor and then leaving off the loadUsers$ line. Devs can then define and implement new effects as needed.

I used the @Effect{dispatch: false} method.

An alternative is to add a second action FooLoaded and have the effect mapTo(new FooLoaded()) to show that the all the feature components are registered and working.

However, I'm open for whatever is clear and fixes the behavior.

It's got me a few times and I'm always initially stumped for why my tab gets the spinner of doom.

I'd prefer to leave the effect in the class and comment it out. Its easier to delete the code, or uncomment it rather than having to add it. Slightly related to #1529 also.

After upgrading to 7.x (from 6.x) , I have exactly the same problem

How was this not the case in 6.x? Generating a feature does not dispatch the newly created action, and if you dispatch that action before doing anything with the effect you will get caught in a loop.

Was this page helpful?
0 / 5 - 0 ratings