Skip to content

Help: Code splitting multiple Epics (if I am using them right) #305

@gregkopp

Description

@gregkopp

I have been working on an Angular2 application as a learning project. It has many small components, each with it's own service, reducer and actions. I had originally written it using @ngrx, but have been spending the last few days learning and refactoring it for ng2-redux, as that is what my employer is using for a new project to which I am hoping to get assigned.

However, I am confused on how to use Epics properly. My previous application relied on Side Effects and was working quite well, and I am having difficulty understanding how to accomplish the same thing in ng2-redux.

For example, my main app is a zoo animal management application, and each kind of animal has it's own code. The animals are retrieved via individual calls to an API. Once the application starts, an action is dispatched from the application level to load data (i.e.: '[App] Load Animal Data'). Each animal subsection would "listen" for this action and call the appropriate service. With @ngrx, I simply added an Injectable class and decorated a function as an Effect:

@Injectable()
export class ElephantEffects {

  constructor(
    private actions$: Actions,
    private actions: ElephantActions,
    private service: ElephantDataService
  ) { }

  @Effect() loadData = this.actions$
    .ofType(AppActions.LOAD_DATA)
    .switchMap(x => this.service.getAll())
    .map(g => this.actions.loadSucceeded(g));

I then exported an array of effects:

export const EFFECTS = [
  EffectsModule.run(ElephantEffects),
  EffectsModule.run(LionEffects),
];

This final collection was declared as an import in the top level Zoo module.

@NgModule({
  imports: [
    ...EFFECTS
  ]
})
export class AppModule { }

Simple enough in @ngrx. Seems to be a different level of difficulty with ng2-redux.

I've looked at the docs for combineEpics and even adding Epics asynchronously, but it's not clicking for me for some reason. What I don't want to have to do is import each of these in the top level, and declare each Epic in the configureStore call in the top level component.

I've tried creating an Epic like this:

@Injectable()
export class ElephantEpics {
  constructor(
    private appActions: AppActions,
    private service: ElephantService) { }

  loadData = (action$: ActionsObservable<AppActions>) => {
    return action$.ofType(AppActions.LOAD_DATA)
      .flatMap(() => this.service.getAll());
  }
}

But have't had any luck actually getting this into the middleware. Plus, I would have to define every class and function in the App Module, from what I am reading. I'd much rather look at combining these from level to level. Should I need to add a new side effect, I would only need to add it at it's lowest level.

Looking for some guidance and suggestions. What am I missing here?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions