Перебирать элементы и возвращать Observable для массива

У меня есть Observable, где у пользователя есть свойство массива Posts[], которое я хочу перебрать, вызвать метод с промежуточными значениями и затем вернуть Observable с результирующими объектами в виде массивов.

На данный момент у меня есть следующий код, который работает:

    public ngOnInit() {
    const results: any[] = [];
    this.controlData$ = this.controlContent$
        .pipe(
            filter((input) => input !== null),
            flatMap((p: IControlContentSection) => p.controlPerformers),
            map((m: IControlPerformer) => {
                results.push({
                        ...m,
                        nextOccurrence: this.getNextControlDate(m.controlFrequency, m.firstOccurrence),
                    });
                return results;
                }),
            takeUntil(this.destroy$),
            );
}

Я использую переменную массива results: any[], но мне не нравится это решение, поскольку оно опирается на эту внешнюю переменную, поэтому оно работает только при инициализации компонента.

Я пытался использовать toArray() или reduce((x, y) => x.concat(y), []) после карты, но затем преобразуется в шаблон в значение NULL.

Как я могу вернуть Observable без необходимости использования внешней переменной?

В шаблоне я подписываюсь через асинхронный канал:

<div *ngIf="controlData$ | async as controllers">
  ...
  <div *ngFor="let ctrl of controllers; trackBy:ctrl?.userId">
  ...
  </div>
</div>

1 ответ

Решение

Вы делаете это правильно после карты, она должна работать. Но для имитации вашего точного поведения вам нужен оператор сканирования. Оператор сканирования будет выдавать промежуточные значения, так как вы возвращаете свой массив результатов. Вы пробовали это так?

 public ngOnInit() {
    this.controlData$ = this.controlContent$
    .pipe(
        filter((input) => input !== null),
        flatMap((p: IControlContentSection) => p.controlPerformers),
        map((m: IControlPerformer) => {
            return {...m,
                    nextOccurrence: this.getNextControlDate(m.controlFrequency, m.firstOccurrence),
                };
         }),
         scan((acc, cur) => [...acc, cur], [])
         takeUntil(this.destroy$),
        );
}

Это должно сработать, если нет, я мог бы предоставить вам вантуз или около того.

Надеюсь это поможет.

Другие вопросы по тегам