angular - @ngrx/effects 给出 TypeError : You provided 'undefined' where a stream was expected. 您可以提供 Observable、Promise、Array 或 Iterable

标签 angular observable rxjs5 ngrx

我有一个场景,我需要在我的 Angular 应用程序中对两个 @Ngrx 操作进行排序。

第一个操作使用一些数据更新状态,第二个操作使用该数据触发服务器调用。我正在使用 Effect 对两个 Action 进行排序,并仅在第一个 Action 完成后触发第二个 Action 。

为确保第二个操作包含状态中最近更新的数据,我将存储注入(inject)到我的效果中并使用选择器函数检索数据并将其作为第二个操作的有效负载包含在内。

这行得通。

我的问题

但是,我相信由于 this.actions$ 已经是一个可观察的流,我应该能够简单地转换该流上的每个事件并将其转换为不同的操作。

我的想法的粗略大理石图: rough idea

我正在使用 withLatestFrom 运算符将 Action 流与来自状态的数据结合起来。

  @Effect()
  lazyEffect1$ = this.actions$.ofType(LazyActions.TEST_ACTION_SEQUENCE)
     .withLatestFrom(this.filterId$, (x, y) => {
       return new LazyActionDone(y.number);
     });

但是这段代码给我一个错误:

TypeError:您在需要流的地方提供了“未定义”。您可以提供 Observable、Promise、Array 或 Iterable。

我已经能够使用稍微不同的构造来实现它,它也包含在下面的代码中。

但我想了解为什么 lazyEffect1 不起作用。我的理解在哪里失败了?

代码

NgRx Reducer:

// reducers.ts
export function lazyReducer(
  state: any = {},
  action: LazyAction | LazyActionDone
) {

  switch (action.type) {
    case LazyActions.TEST_ACTION_SEQUENCE: {
      console.info('Action Received in Reducer: ', action.type);
      return {
        ...state,
        number: action.payload
      };
    }

    case LazyActions.TEST_ACTION_SEQUENCE_DONE: {
      console.info('Done Received in Reducer: ', action.type);
      return {
        ...state,
        retrieved: action.payload,
        done: true
      };
    }

    default: {
      return state;
    }
  }
}

NgRx 的影响:

// effects.ts
@Injectable()
export class LazyEffects {
  private filterId$: Observable<any>;

  constructor(
    private actions$: Actions,
    private store: Store<any>
  ) {
    this.filterId$ = this.store.select(getLazyState);
  }

  // THIS DOES NOT WORK
  @Effect()
  lazyEffect1$ = this.actions$.ofType(LazyActions.TEST_ACTION_SEQUENCE)
     .withLatestFrom(this.filterId$, (x, y) => {
       // console.info(x, y);
       return new LazyActionDone(y.number);
     });

  // THIS WORKS
  @Effect()
  lazyEffect2$ = this.actions$.ofType(LazyActions.TEST_ACTION_SEQUENCE)
    .switchMap((action) => {
      console.info('Action Received in Effects: ', action.type);
      return of(action).withLatestFrom(this.filterId$, (x, y) => new LazyActionDone(y.number));
    });
}

最佳答案

只是为了说明解决方案 @cartant provided ..我相信解决方案是替换此属性:

  // THIS DOES NOT WORK
  @Effect()
  lazyEffect1$ = this.actions$.ofType(LazyActions.TEST_ACTION_SEQUENCE)
     .withLatestFrom(this.filterId$, (x, y) => {
       // console.info(x, y);
       return new LazyActionDone(y.number);
     });

有了这个功能:

  @Effect()
  lazyEffect1$() { 
     return this.actions$.ofType(LazyActions.TEST_ACTION_SEQUENCE)
     .withLatestFrom(this.filterId$, (x, y) => {
       // console.info(x, y);
       return new LazyActionDone(y.number);
     });
   }

@cartant他在评论中的回答值得赞扬,但我想为遇到此问题但没有注意到答案在评论中的任何其他人提供答案/示例。

关于angular - @ngrx/effects 给出 TypeError : You provided 'undefined' where a stream was expected. 您可以提供 Observable、Promise、Array 或 Iterable,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48938426/

相关文章:

html - 如何在 CSS 中创建响应式箭头指针形状?

html - 无法使用向后兼容的 CSS 定位元素

angular - TS2339 : Property 'assign' does not exist on type

Rxjs:Observable.combineLatest 与 Observable.forkJoin

node.js - rxjs 的 angular-cli 安装问题

Angular2 获取元素/组件样式的正确方法

android - 用 RxJava 替换监听器

angular - Rxjs 6 等效于 Observable.create(subscriber -> {...}).share()

javascript - 如何测试 RxJS 事件

javascript - 从外部访问源 observable Rx.Observable.prototype