NgRx createSelector是否可能发出错误?

时间:2019-11-21 18:37:28

标签: angular rxjs ngrx ngrx-entity

也许有另外一种解决方法(例如,创建另一个特别用于错误的选择器)

    export const getMSFState = createFeatureSelector<STState>('st');
    export const selectCreatedSensor = createSelector(
        getMSFState,
        selectAllSensors,
        (state: STState, sensorArray: SeasonTotals[], props: { blockId: number}) => {
            const isSuccessCreate = state.action === fromST.ST_ADD_ELEMENT && !state.loading && !state.error;
            const isAnErrorCreate = state.action === fromST.ST_ADD_ELEMENT && !state.loading && state.error;
            if (isAnErrorCreate) {
                return throwError('Error X');
            }
            const blockSensors = [...sensorArray].filter(s => s.blockId = props.blockId);
            return isSuccessCreate ? blockSensors.pop() : null;
        }
    );

我想捕获第二个订阅参数(错误一),但我不知道是否可以在NgRx选择器中发射它

    this.store.pipe(
        select(STSelectors.selectCreatedSensor, { blockId: this.id })
    ).subscribe((data) =>  {
        console.log('success creation', data);
    }, (error) => {
        // I can't catch this, instead I catch it in the first subscribe parameter (in the success one)
        // And the value emited is an Observable object
        console.log('something went wrong', error); 
    })

2 个答案:

答案 0 :(得分:1)

选择器是纯函数,我发现在选择器(和简化器)中引发错误是一种不好的做法。您应该改为返回一个值(nullundefined,空对象...)。

答案 1 :(得分:0)

选择器总是返回有关state中当前store而不是stream的部分信息。

throwErrorobservable流返回错误,因此您无法返回实际状态。

...基本上,将发生的情况是,当选择器中的Observable<Observable<Error>>函数返回时,您将得到类似throwError的内容,因此将不起作用。

...

首先:您使用的商店有误,应该:

  • 发送getData事件
  • 如果发生错误:getDataError事件
  • 成功完成getDataSuccess事件

我的方法是创建一个独占的loadingSelector loadedSelectorerrorSelector,将数据加载包装在servicefacade或您要调用的任何内容中并在那里进行错误处理,以便您可以正确订阅组件:

getData(): Observable<MyData> {
   return this.store.select(selector.loaded)
     .pipe(
       switchMap(loaded => {
          if (loaded) {
             return this.store.select(selector.myData);  // if data already loaded return it
          }
          this.store.dispatch(loadingAction);  // dispatch loading event
          return this.store.select(selector.loading) // select the loading state
       })
       filter(loading => !loading), // wait until loading changes to false
       switchMapTo(this.store.select(selector.error)), // get current error state
       switchMap(error => { 
          if (error) {
            return throwError(error); // throw error if exits
          }
          return this.store.select(selector.myData); // otherwise return data
       })
     }
}