Проверьте данные в Angular Store перед вызовом API с помощью NGRX с использованием наблюдаемых

Я использую Angular с эффектами NGRX, и я новичок в мире наблюдаемых. Я хочу проверить, что если данные существуют в моем хранилище, то API не должен вызываться, а данные должны извлекаться из хранилища. Мне удалось найти, что я могу использовать withLatestFrom(), который может проверить последнее значение в магазине. Следующая часть сбивает меня с толку, и я не могу заставить его работать. Мой текущий код ниже:

 @Effect() getSomeContent$ = this.actions$
    .ofType(GET_SOME_CONTENT)
    .withLatestFrom(this.store$.select('store-section'))
    .map(([action, store]) => {
        const content = {};
        if (store.someContent.length > 0) {
           return new GetCategoryContentSuccessAction({ categoryContent: categories });
        }
        return Observable.from(action.payload);
    })
    .switchMap(payload => this.APIcall(payload)
        .then(data => {
            const content = {};
            data.items.map((item) => {
                const slug = data.slug;
                content[slug] = {
                    info: datasomeData
                };
            });
            return new GetSomeContentSuccessAction({ categoryContent: categories });
        })
        .catch((err) => {
            return new GetFailureAction({ error: {} });
        })
    );

Я хочу использовать какой-то оператор if или else для проверки магазина. Если данные существуют, я хочу отправить пустой объект обратно для редуктора, который я должен обработать. Если это не так, я хочу вызвать API и отправить эти данные обратно. Я не знаю, может ли наблюдаемое быть разветвленным другими словами, чтобы это можно было сделать?

Есть ли лучший способ, которым это могло быть достигнуто? Возможно, путем создания другого действия, чтобы иметь дело с API отдельно. Я хотел бы узнать, какова лучшая практика в будущем. Любая помощь будет принята с благодарностью.

1 ответ

Я просто работал над решением этой конкретной проблемы, поэтому я решил поставить свои 2 цента здесь на тот случай, если кто-то еще сочтет это полезным.

Есть отличная статья о том, как использовать NGRX-эффекты для этого. Это говорит о том, насколько сложно попытаться втиснуть это в цепочку эффектов ngrx.

Вместо этого они рекомендуют использовать сервис, который я использую и люблю. Простая версия может выглядеть следующим образом.

Service: 

public posts$ = this.store.select(postSelectors.selectAll)
    .pipe(
        tap(posts => {
            if (!posts.length) {
                this.store.dispatch(new postActions.LoadMany());
            }
        }),
        filter(posts => posts !== null)
    );

Здесь мы в основном просто пытаемся выбрать часть состояния, которое нам нужно, и, если его там нет, отправляем действие, которое вызывает эффект, чтобы получить его из API и отправить его в магазин.

Component: 

this.posts$ = this.postService.posts$;

Тогда в вашем компоненте вы можете просто подписаться на наблюдаемые из вашего сервиса и не заботиться о том, есть ли он в магазине или нет. Затем вы можете либо подписаться на это в своем компоненте, чтобы получить значение, либо отправить его в шаблон с асинхронным каналом.

Это очень хорошо работает для простых вещей, но я все еще работаю над более сложными цепочками RXJS для случаев, когда вам нужно получить данные, которые зависят от других данных, которые существуют в первую очередь. Но это всего лишь ограничение моих способностей при написании функций RXJS.

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