0
\$\begingroup\$

I have an API that provides data that is updated on an infrequent schedule, about once every 2½ minutes on average. Assuming that it's okay to fetch only as often as every 2½ minutes or less often, I'd like to construct a saga (I use redux-saga) in a way that it does nothing if it's not yet time to do an API call. The code I came up with is quite simplistic (API error handling omitted):

import { select, put, call } from "redux-saga/effects";

const FETCH_INTERVAL = 1000 * 60 * 60 * 2.5;

function* fetchApiSaga(apiUrl) {
  // get data from the store
  const data = select(state => state.theDataWeNeed);

  // signal to the user that we're about to fetch data
  put(WAITING_FOR_DATA);

  // if fetched 2.5 ago or earlier, fetch again
  if (!data || new Date() - !data.lastFetchedAt > FETCH_INTERVAL) {
    const response = yield call(apiUrl);

    // signal to the user that now we have new data from the API
    put(REWRITE_DATA, response);
  } else {
    // signal to the user that we just reuse old data
    put(JUST_USE_CACHED_DATA);
  }
}

Now, I have two questions:

  1. Is this an idiomatic way to suppress consecutive actions in Redux Saga based on time?
  2. Is this idiomatic Redux Saga if the generator function selects from the store and therefore is not pure?
\$\endgroup\$
0
\$\begingroup\$

Disclaimer: I´m not an expert in redux / redux-saga. This post is not directly answering your questions. Rather, it is focused on code design / architecture and what is the most useful approach for the underlying problem.

For me, the main question is: Who is in charge of determining when the data is invalid?

Imho, there are at least three answers to this:

  1. The API / backend / server
  2. The frontend application
  3. One particular UI component

If it is 1., then I would use HTTP cache headers like Cache-Control: max-age=150. This way, the backend can change the value without requiring to adapt the frontend. Also, it removes the need for any conditional code. The saga can always call the API and the browser does the caching.

If it is 2., then the saga should contain the conditional code to determine whether to fetch new data or to used cached values. Where to put the actual cache and how to do this is a question on its own with regards to frontend application architecture.

If it is 3., then the particular UI component should contain the conditional code and it should also contain / be in charge of the cached values.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.