I have an API that provides data that is updated on an infrequent schedule, about once every 21⁄2 minutes on average. Assuming that it's okay to fetch only as often as every 21⁄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:
- Is this an idiomatic way to suppress consecutive actions in Redux Saga based on time?
- Is this idiomatic Redux Saga if the generator function
select
s from the store and therefore is not pure?
-
\$\begingroup\$ does this help? github.com/redux-saga/redux-saga/blob/master/docs/advanced/… \$\endgroup\$user50167– user501672019年11月08日 14:07:39 +00:00Commented Nov 8, 2019 at 14:07
-
\$\begingroup\$ It's a bit reverse: race starts two sagas and finishes as soon as any of them finishes. My question is more about finishing a saga and not starting it (i.e. not executing the generator function again) until some time has passed since the previous call. But I'll look into this as well, thanks! \$\endgroup\$rishat– rishat2019年11月08日 17:15:50 +00:00Commented Nov 8, 2019 at 17:15
1 Answer 1
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:
- The API / backend / server
- The frontend application
- 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.