Search code examples
angulartypescriptngrxngrx-storengrx-effects

ngrx - Weird Behavior on Effects


As stated in the title, I'm facing an issue where all of my effects work properly only in these cases:

  • I'm already logged in
  • I'm not logged in

If I manage to logout and login with another user the problem occurs. Only each ngOnInitdoing the action dispatch gets called. No effects get fired.

I have two modules, app.module and pages.module. The first one declares only components for not logged in users such as, login/register/reset. The second ones declares only components for the logged in user.

In app.module.ts I import all the reducers and set them up like StoreModule.provideStore(reducer). In pages.module.ts, another module, I import and activate the effects like EffectsModule.run(TestEffects).

With the following code only the log inside ngOnInit gets called. A log inside the effect never gets called.

test.component.ts:

/** ngrx **/
import * as reducers from '../../reducers';
import * as testActions from './actions/test.actions';

. . .

constructor(private _store: Store<reducers.State>){
    this._store.select(reducers.getStuff)
        .subscribe(stuff => console.log(stuff));
}

ngOnInit() {
    console.log('Dispatching Load Action');
    this._store.dispatch(new testActions.LoadAction());
}

test.actions.ts:

import { Action } from '@ngrx/store';

export const ActionTypes = {
    LOAD: type('[Test] Load'),
    LOAD_SUCCESS: type('[Test] Load Success'),
};

export class LoadAction implements Action {
    type = ActionTypes.LOAD;
    constructor() {}
}

export class LoadActionSuccess implements Action {
    type = ActionTypes.LOAD_SUCCESS;
    constructor(public payload: SomeType) {}
}

export type Actions
  = LoadAction
  | LoadActionSuccess

test.effects.ts:

@Injectable()
export class TestEffects {
  @Effect() load$ = this.actions$
    .ofType(testActions.ActionTypes.LOAD)
    .map(toPayload)
    .switchMap(() => this._testService.getStuff()
      .map(result => new testActions.LoadActionSuccess(result))
      .catch((error) => Observable.of({type: error}))
    )
  ;

  constructor(private _testService: TestService, private actions$: Actions) {}
}

test.reducer.ts:

import { createSelector } from 'reselect';
import { Action } from '@ngrx/store';
/** ngrx **/
import * as sidebarActions from '../actions/test.actions';

export interface State {
    stuff: SomeType
};

export const initialState: State = {
    stuff: new SomeType()
};

export function testReducer(state = initialState, action: Action): State {
    switch (action.type) {
        case testActions.ActionTypes.LOAD_SUCCESS:
            return {
                stuff: new SomeType(action.payload)
            }
        default: {
            return state;
        }
    }
}

export const getStuff = (state: State) => state.stuff;

In my package.json I have:

{
    "dependencies" : {
        "@angular/core": "^4.0.0",
        . . .,
        "@ngrx/core": "^1.2.0",
        "@ngrx/effects": "^2.0.4",
        "@ngrx/store": "^2.2.3",
        . . .
    },
    "devDependencies" : {
        . . .
        "ngrx-store-freeze": "^0.1.9",
        . . .
    }
}

I don't really understand this behavior. I also took a loot on ngrx github issues and related questions like this one but I'm not really able to solve this.

I'm guessing it may be caused by the fact that I have these two different modules

EDIT:

Moving the effects and their services inside app.module leads to the same behavior.

What Am I doing wrong?


Solution

  • It came out the problem was caused by an old version of ngrx. I managed to upgraded everything to version 4.1.1 following the migration guide and the different instructions in READMEs.