首页 > 解决方案 > 传递给`selectId`实现的实体返回未定义

问题描述

我想在ngrx中设置令牌和刷新令牌,并为每个请求保存并使用它,当页面重新加载时,不要删除redux中的数据。

我为此实现了这个状态:

我发送数据:

            this.getUserInformation().toPromise().then(responset => {
            if (response.success === true) {
                this.store.dispatch(new SetUserInformation({
                    displayName: responset['result']['displayName'],
                    userInfo: responset.result.claims,
                    RefreshTokenStatus:false,
                    accessToken:response['result']['access_token'],
                    refreshToken:response['result']['refresh_token']
                }))
            }
        });

在模块中我定义商店:

    StoreModule.forFeature('Information', reducer),
    EffectsModule.forFeature([])

这是我的减速机:

   const initialState = adapter.getInitialState({
    accessToken: null,
    refreshToken: null,
    RefreshTokenStatus: false,
    userInfo: null,
    displayName: null
})

export function reducer(state = initialState, action: TokenAction): TokenState {

    switch (action.type) {
        case TokenActionTypes.UserInformation:
            return adapter.addOne(action.payload, state)
        default:
            return state;
    }
}

这是我的模型:

  export interface TokenState {
    accessToken: string;
    refreshToken: string;
    RefreshTokenStatus: boolean;
    userInfo: string[];
    displayName: string;
}

这是我的Selector

export interface State extends fromState.State, EntityState<TokenState> {
    UserInfo: TokenState;
}

export const adapter: EntityAdapter<TokenState> = createEntityAdapter<TokenState>();
const getTokenFetureState = createFeatureSelector<TokenState>('Information');


export const getAccessToken=createSelector(
    getTokenFetureState,
    state => state.accessToken
)

这是行动:

   export class SetUserInformation implements Action {
    readonly type = TokenActionTypes.UserInformation;

    constructor(public payload: TokenState) {
    }
}

export type TokenAction = SetUserInformation

现在我有两个问题:

 this.store.pipe(select(fromTokenSelect.getAccessToken)).subscribe(data=>{
     console.log(data)
 })

答:当我想获取使用它的令牌时,它返回 null 并向我显示此错误:

@ngrx/entity:传递给selectId实现的实体返回未定义。您可能应该提供自己的selectId实现。被传递的实体:ObjectselectId实现:(instance) => instance.id

B:重新加载页面时,它会从ngrx中删除数据。

我怎么解决这个问题 ?

在此处输入图像描述

标签: javascriptangulartypescriptngrxngrx-entity

解决方案


您正在使用ngrx/entity非实体数据。实体设计用于处理数据数组,其中每个元素都有某种唯一标识符。这就是它抛出错误的原因:您正在为其提供非实体兼容的数据。您需要编写一个简单的 reducer 来设置状态,而不是尝试将数据添加到不存在的实体。

至于页面重新加载,NgRx 将始终重置数据,这是预期的行为。localStorage如果你想随着时间的推移持久化数据,你需要实现保存。


推荐阅读