简体   繁体   中英

Fix angular-redux/store after upgrade to 9.0 and angular 7

I have taken over an existing angular application which I am in the process of updating to version 7 from 5. For state-management, it is using @angular-redux which was updated to version 9.0. However keeping the store as is has caused the app to not load (with no console errors).

I have changed the function in each individual epic as shown in the code as told do in the terminal. However I have not found a resource as to how to adapt the main store.ts file that the project is running, which is breaking the app. If anyone knows what to put in that file, to make the store be set up appropriately, please do share.

store.ts:

import { NgModule } from "@angular/core";
import {
  NgReduxModule,
  NgRedux,
  DevToolsExtension
} from "@angular-redux/store";
import { NgReduxRouterModule, NgReduxRouter } from "@angular-redux/router";
// The top-level reducers and epics that make up our app's logic.
import { IModel, initialData } from "./model";
import { rootReducer } from "./reducer";

import { Epic } from "./epic";
import { StorageService } from "./storage-service";
// DataModels
import { ApplicationStateModule } from "./application-state/module";
import { EntitiesModule } from "./entities/module";
import { LiveDataModule } from "./live-data/module";
import { RouterModule } from "./router/module";
import { StoreSelectors } from "./selectors";
import { TimePeriodModule } from "./time-period/module";
import { TimeSeriesDataModule } from "./time-series-data/module";
import { SelectorsModule } from "../selectors/selectors.module";
import { PointInTimeModule } from "./point-in-time/module";
import { applyMiddleware, createStore } from "redux";
import { createEpicMiddleware } from "redux-observable";

@NgModule({
  imports: [
    NgReduxModule,
    NgReduxRouterModule.forRoot(),
    ApplicationStateModule,
    EntitiesModule,
    LiveDataModule,
    RouterModule,
    ...Module,
    ...Module,
    ...Module,
    ...Module
  ],
  providers: [Epic, StoreSelectors, StorageService]
})
export class Store {
  constructor(
    public store: NgRedux<IModel>,
    devTools: DevToolsExtension,
    ngReduxRouter: NgReduxRouter,
    rootEpic: Epic,
    storageService: StorageService
  ) {
    store.configureStore(
      rootReducer,
      storageService.fromStore(initialData),
// the commented code below breaks the app if either line is uncommented
      // [...rootEpic.createEpics()],

      // devTools.isEnabled() ? [devTools.enhancer()] : []
    );
    if (ngReduxRouter) {
      ngReduxRouter.initialize();
    }
  }
}

Here is an example of one of the specific epic.ts files:

import { Injectable } from '@angular/core';
import { Actions } from './actions';
import { Actions as ApplicationStateActions } from '../applicationstate/actions';
import { createEpicMiddleware } from 'redux-observable';
import { createStore, applyMiddleware } from 'redux';
import { rootReducer } from '../reducer';

@Injectable()
export class Epic {
  constructor(
    private actions: Actions,
    private applicationStateActions: ApplicationStateActions
  ) {}

  load = (action$) =>
    action$
    .ofType(Actions.SET_DATES_AVAILABLE)
      .map((action) => {
        return this.actions.setUnit(2);
      })
    .ofType(Actions.SET_UNIT)
      .map((action, state) => {
        return this.applicationStateActions.updateTimePeriodStatus('ready');
      })

  public createEpics() {
  const epicMiddleware = createEpicMiddleware();
  const store = createStore(rootReducer, applyMiddleware(epicMiddleware));
// tslint:disable-next-line: no-void-expression
 return [epicMiddleware.run(this.load)];

//below is the original way it was, above is the change the terminal said to do,
//see https://github.com/redux-observable/redux-observable/blob/master/MIGRATION.md

// return [createEpicMiddleware(this.load)];

  }
}

In case it helps anyone, this is the final way the code looked in order to work.

RootEpic.ts:

import { Injectable } from "@angular/core";
import { Epic as xxxxxStateEpic } from "./application-state/epic";
import { Epic as bbbbbbEpic } from "./entities/epic";
import { Epic as ggggggEpic } from "./live-data/epic";
import { Epic as fffffEpic } from "./time-period/epic";
import { Epic as dddddDataEpic } from "./time-series-data/epic";
import { Epic as qqqqqqEpic } from "./point-in-time/epic";

@Injectable()
export class RootEpic {
  constructor(
    private xxxxxStateEpic: xxxxxStateEpic,
    private bbbbEpic: bbbbbEpic,
    private gggggEpic: gggggEpic,
    private fffffEpic: ffffffEpic,
    private ddddddData: ddddddEpic,
    private qqqqqEpic: qqqqqqqEpic
  ) {}

  public createEpics() {
    return [
      ...this.gggggEpic.createEpics(),
      ...this.bbbbbbEpic.createEpics(),
      ...this.fffffffEpic.createEpics(),
      ...this.xxxxxStateEpic.createEpics(),
      ...this.qqqqqqqEpic.createEpics(),
      ...this.dddddData.createEpics()
    ];
  }
}

each specific epic ended in:

myEpic = (action$, state$) =>
...... end of myEpic,

 createEpics(){
return [this.myEpic];
}

finally the store.ts file should look like this

@NgModule({
  imports: [
    NgReduxModule,
    NgReduxRouterModule.forRoot(),
   ...(list out modules here)
  ],
  providers: [RootEpic, StoreSelectors, StorageService]
})
export class Store {
  constructor(
    public store: NgRedux<IModel>,
    devTools: DevToolsExtension,
    ngReduxRouter: NgReduxRouter,
    rootEpic: RootEpic,
    storageService: StorageService
  ) {
    const epicMiddleware = createEpicMiddleware();

    store.configureStore(
      rootReducer,
     storageService.fromStore(initialData),
     [epicMiddleware],
      devTools.isEnabled() ? [devTools.enhancer()] : []
    );

    epicMiddleware.run(combineEpics(...rootEpic.createEpics()));
    if (ngReduxRouter) {
      ngReduxRouter.initialize();
    }
  }
}

Enjoy!!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM