Skip to content

Instantly share code, notes, and snippets.

@shubhanus
Created September 9, 2018 17:10
Show Gist options
  • Save shubhanus/01d2266f0f5774d650584af18d909852 to your computer and use it in GitHub Desktop.
Save shubhanus/01d2266f0f5774d650584af18d909852 to your computer and use it in GitHub Desktop.
Redux + redux-saga polling
<h1>redux-saga polling example</h1>
<div class="controls">
<button class="controls-item" id="pollStartBtn">Poll Start</button>
<button class="controls-item" id="pollStopBtn">Poll Stop</button>
<pre class="controls-item" id="pollingState">Polling false</pre>
</div>
<div class="response">
<h3 id="responseState"><em>Start polling to see random jokes...</em></h3>
</div>
<script>
// Set up globals
const createSagaMiddleware = ReduxSaga.default;
const { delay } = ReduxSaga;
const { take, put, call , race } = ReduxSaga.effects;
const { createStore, combineReducers, applyMiddleware } = Redux;
// Set up API endpoint to use for the example.
const ENDPOINT = 'https://08ad1pao69.execute-api.us-east-1.amazonaws.com/dev/random_joke';
</script>
/**
* Saga worker.
*/
function* pollSaga(action) {
while (true) {
console.log("polling")
try {
const { data } = yield call(() => axios({ url: ENDPOINT }));
console.log("DATA")
yield put(getDataSuccessAction(data));
console.log("redux")
yield call(delay, 4000);
console.log("delay")
} catch (err) {
yield put(getDataFailureAction(err));
}
}
}
/**
* Saga watcher.
*/
function* watchPollSaga() {
while (true) {
console.log("watching", "POLL_START")
yield take(POLL_START);
console.log("race", "POLL_STOP")
yield race([
call(pollSaga),
take(POLL_STOP)
]);
}
}
/**
* Set up of Redux and the view layer.
*/
/**
* ACTION TYPES.
* - Redux Boilerplate
*/
const POLL_START = 'POLL_START';
const POLL_STOP = 'POLL_STOP';
const GET_DATA_SUCCESS = 'GET_DATA_SUCCESS';
const GET_DATA_FAILURE = 'GET_DATA_FAILURE';
/**
* Action Creators.
* - Redux Boilerplate
*/
const pollStartAction = () => ({ type: POLL_START });
const pollStopAction = () => ({ type: POLL_STOP });
const getDataSuccessAction = payload => ({ type: GET_DATA_SUCCESS, payload });
const getDataFailureAction = payload => ({ type: GET_DATA_FAILURE, payload });
/**
* Reducer.
* - Redux Boilerplate
*/
const initialState = {
data: false,
polling: false,
};
const dataReducer = (state = initialState, action) => {
switch (action.type) {
case POLL_START:
return {
...state,
polling: true,
}
case POLL_STOP:
return {
...state,
polling: false,
}
case GET_DATA_SUCCESS:
return {
...state,
data: action.payload
};
default:
return state;
}
};
/**
* Create the store.
* - Redux Boilerplate
*/
const sagaMiddleware = createSagaMiddleware();
const createStoreWithMiddleware = applyMiddleware(sagaMiddleware)(createStore);
const store = createStoreWithMiddleware(
dataReducer,
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
);
sagaMiddleware.run(watchPollSaga);
/**
* Handle the view.
* - Typically would be handled by something like React / Angular etc.
*/
const pollStartBtn = document.getElementById('pollStartBtn');
const pollStopBtn = document.getElementById('pollStopBtn');
const pollingState = document.getElementById('pollingState');
const responseState = document.getElementById('responseState');
pollStartBtn.addEventListener('click', () => {
store.dispatch(pollStartAction())
});
pollStopBtn.addEventListener('click',() => {
store.dispatch(pollStopAction());
});
store.subscribe(() => {
const { data, polling } = store.getState();
pollingState.textContent = `Polling ${polling}`;
if (data) {
responseState.innerHTML = `${data.setup}<br/>— <em>${data.punchline}</em>`;
}
});
html {
font-family: sans-serif;
color: #333;
}
responseState {
font-weight: 600
}
#responseState em {
font-weight: 400
}
.controls {
display: flex;
margin-bottom: 20px;
}
.controls-item {
margin-right: 20px;
}
.response {
background-color: #eee;
padding: 10px 20px;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment