Эффект ngrx 8 не срабатывает для второй отправки - PullRequest
0 голосов
/ 20 марта 2020

У меня есть мертвая простая структура ngrx, которая загружает массив JSON из конечной точки REST и переводит его в состояние. Он загружает не весь массив сразу, а на страницах из 30 элементов, и результат добавляется к тому, что было загружено ранее. Так что это типичная нумерация страниц. Действие, отвечающее за всю операцию, отправляется неоднократно, с параметром, указывающим номер страницы для загрузки. Он вызывает эффект, который, в свою очередь, вызывает метод службы.

Проблема в том, что действие не выполняется вообще после первого вызова. При первом звонке работает отлично. На втором, третьем и др. c. попытка его остановить до оператора act(), но он не выдает никаких ошибок или вообще ничего не делает.

Вот действие:

export const LoadSiteList = createAction(
    ActionTypes.LoadSiteList,
    props<{ page: number }>()
);

Эффект:

    loadSiteList = createEffect(() => this.actions.pipe(
        ofType(LoadSiteList),
        act({
            project: payload => {
                return this.sitesService.loadSiteList(payload['page']).pipe(
                    map((siteList: Site[]) => UpdateSiteList({ siteList })),
                )
            },
            error: () => { alert('Unable to load site list!'); return DoNothing() }

        })
    ));

Метод обслуживания в sitesService:

  loadSiteList(page: number = 1): Observable<any> {
    return Observable.create(observer => {
      const temp = this.httpClient.get(`${environment.rootUrl}sites?_page=${page}`)
        .subscribe(
          data => observer.next(data),
          error => observer.error(error),
          () => temp.unsubscribe()
        );
    });
  }

И вот как я вызываю его из моего компонента:

this.store.dispatch(LoadSiteList({ page: this.page }));

Я почти уверен, что это не пропущенный импорт, потому что тогда он вообще не будет работать. unsubscribe() в методе обслуживания также не виноват. Я попытался поместить оператор tap() между ofType () и map() в эффекте, и он срабатывает, так что действие действительно происходит. Любой консольный вывод в ветвях обратного вызова оператора act() не появится, поэтому оператор не сработает. Но почему?

На всякий случай вот и метод редуктора. Это никогда не вызывается, хотя.

    on(
        SitesActions.UpdateSiteList,
        (state, siteList) => ({
            ...state,
            sites: [...state.sites, ...siteList.siteList]
        })
    ),

1 Ответ

0 голосов
/ 20 марта 2020

Нет ничего лучше, чем отвечать на мой вопрос, чувствуя себя немного глупо. Так что, похоже, ошибка была в структуре канала эффекта. Вот рабочая версия:

loadSiteList$ = createEffect(() => this.actions$.pipe(
   ofType(LoadSiteList),
   map(payload => payload['page']),
   mergeMap(page => this.sitesService.loadSiteList(page)
       .pipe(
           map((siteList: Site[]) => UpdateSiteList({ siteList })),
           catchError(error => { alert(`Error ${error.status} loading data.`); return EMPTY; })
       ))
));

Другой извлеченный урок: ngrx имеет значение EMPTY, когда вы не хотите отправлять другое действие из своего эффекта. Чем больше ты знаешь.

...