簡體   English   中英

@ngrx/entity `Cannot read property 'ids' of undefined` 與 @ngrx/store 一起使用時? 在定義適配器時已經考慮了自定義 ID

[英]@ngrx/entity `Cannot read property 'ids' of undefined` when using together with @ngrx/store? already accounting for custom ids when defining adapter

我已經查看了其他 2 篇關於此的文章,一篇包含較大的 state 的文章不適用,而另一篇注冊了多個 forFeature - 我已經對此進行了一些測試,即使我在之前或之后導入它forRoot(reducers) 在我的 app.module 中,它沒有區別。

我確定我在配置中遺漏了一些明顯的東西。

我的配置:

export const orderAdapter: EntityAdapter<IOrder> = createEntityAdapter<IOrder>({
  selectId: (order: IOrder) => order._id
});

export interface AllOrdersState extends EntityState<IOrder> {}

export const initialState: AllOrdersState = orderAdapter.getInitialState({
  ids: [],
  entities: {}
});

export const OrdersState = createFeatureSelector<AllOrdersState>('orders');

export const {
  selectIds,
  selectEntities,
  selectAll,
  selectTotal
} = orderAdapter.getSelectors(OrdersState);

我的實際減速器:


export function ordersReducer(
  state: AllOrdersState = initialState,
  action: actions.OrdersActions
) {
    case actions.CREATE_MANY: {
      console.log(action.orders);
      return orderAdapter.addMany(action.orders, state);
    }
}

我在我的 Order.Module 中注冊為:

    StoreModule.forFeature('orders', ordersReducer),

我的主減速機map:

const reducers: ActionReducerMap<AppState> = {
  order: orderReducer,
  admin: adminReducer,
  tlabs: tlabsReducer,
  reports: reportsReducer,
  settings: settingsReducer,
  orders: ordersReducer
};

然后是app.module中的主要導入:

    StoreModule.forRoot(reducers),

嘗試讀取實體:

構造函數:

 private store: Store<AppState>

實際 function:

this.store
      .select(ordersReducer.selectAll)

該導入的來源:

import * as ordersReducer from '../../../../../store/reducers/orders.reducer';

我在 entity.js(NGRX 實現文件)中遇到了與您類似的錯誤。 就我而言,我有一個延遲加載的模塊,它有自己的 state,最初是未定義的。 由於實體選擇器在獲取實體相關字段(例如 ids)之前不執行任何 null 檢查,因此會導致此錯誤。 我的解決方案是避免使用orderAdapter.getSelectors(OrdersState)而是定義我自己的相當簡單的受保護選擇器:

export const selectIds = createSelector(selectOrderState, (state) => state?.ids);
export const selectEntities = createSelector(selectOrderState, (state) => state?.entities);
export const selectAll = createSelector(selectOrderState, (state) => (state?.ids as Array<string|number>)?.map(id => state?.entities[id]));
export const selectTotal = createSelector(selectOrderState, (state) => state?.ids?.length);

我不喜歡我沒有使用內置選擇器的事實,但至少這不會破壞我的代碼。 我希望 NGRX 團隊提供一種方法來避免這種情況。

我遇到了這個錯誤,因為我使用錯誤的功能鍵設置了我的選擇器:

export const selectIocState = createFeatureSelector<fromIoc.IocState>('this_key_was_wrong');

它應該與您在功能模塊中加載的內容相匹配:

StoreModule.forFeature('feature_key', iocReducer),

看起來它在初始化之前嘗試從OrdersState中讀取。 您的減速器實際上並沒有返回默認的 state 來初始化它; 至少您似乎沒有,在您提供的代碼中。

讓你的減速器返回默認的 state。

export function ordersReducer(
  state: AllOrdersState = initialState,
  action: actions.OrdersActions
) {
    switch(action.type) {
        case actions.CREATE_MANY: {
          console.log(action.orders);
          return orderAdapter.addMany(action.orders, state);
        }

        default: { 
          return state // Here you should return the default state
        }
    }
}

當我忘記將“狀態”作為 adapter.addOne() 的第二個參數添加時,我遇到了同樣的錯誤。 因此,在 OPs 示例中,如果 redcuer 是按以下方式編寫的:

      return orderAdapter.addMany(action.orders); // !! lack of "state" as 2nd param

那么錯誤將完全相同。 就我而言,這是:

Uncaught TypeError: Cannot read properties of undefined (reading 'ids')
    at Object.operation [as addOne] (entity.js?9b56:59:1)
    at eval (eval at <anonymous> (mapping-fields-group.reducer.ts?fd4f:1:1), <anonymous>:1:17)
    at eval (mapping-fields-group.reducer.ts?fd4f:13:1)
    at eval (store.js?d450:1204:1)
    at combination (store.js?d450:215:1)
    at mappingsDataReducers (mappings-data-state.ts?7c86:21:1)
    at eval (store.js?d450:265:1)
    at combination (store.js?d450:215:1)
    at eval (store.js?d450:254:1)
    at computeNextEntry (store-devtools.js?777a:445:1)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM