【问题标题】:Is it possible to emit an error with NgRx createSelector?是否可以使用 NgRx createSelector 发出错误?
【发布时间】:2019-11-21 18:37:28
【问题描述】:

可能有不同的方法来解决它(比如创建另一个选择器,特别是针对错误)

    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); 
    })

【问题讨论】:

  • 我们需要更多细节。你到底想发生什么?
  • 不,这是不可能的,selector 不返回可观察对象,它总是返回一个值,因此您不能使用 throwError
  • 谢谢@Nickolaus,那么你建议做什么作为替代方案?也许为捕获错误创建另一个选择器?
  • ...如果您使用return new Error('xxx') 而不是throwError 会发生什么事情会很有趣
  • 我的建议是创建一个错误属性,并在满足 X 条件时使用减速器填充该属性。如果您需要跨状态执行此操作(组合状态的不同部分),请使用效果来更新减速器。

标签: angular rxjs ngrx ngrx-entity


【解决方案1】:

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

【讨论】:

    【解决方案2】:

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

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

    ...基本上会发生什么是,您将获得类似于Observable&lt;Observable&lt;Error&gt;&gt; 987654327 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
           })
         }
    }
    

    【讨论】:

      猜你喜欢
      • 2018-04-10
      • 2018-06-19
      • 2020-01-28
      • 2023-02-26
      • 1970-01-01
      • 2021-04-08
      • 1970-01-01
      • 2021-12-20
      • 1970-01-01
      相关资源
      最近更新 更多