Skip to content

Instantly share code, notes, and snippets.

@cherta
Last active January 29, 2016 14:35
Show Gist options
  • Save cherta/f3f9a43651edebf907ae to your computer and use it in GitHub Desktop.
Save cherta/f3f9a43651edebf907ae to your computer and use it in GitHub Desktop.
Sagas
import { routeActions, UPDATE_LOCATION } from 'redux-simple-router'
import { take, put, fork, call } from 'redux-saga'
import { show, retrieve } from './actionCreators'
/*
* Small tree structure in a plain hash that works as my backend server.
*/
const fakeDB = {
'/': [
{ id: '/1',
title: '1'
},
{ id: '/2',
title: '2'
}
],
'/1': [
{ id: '/1/a',
title: 'a'
},
{ id: '/1/b',
title: 'b'
}
],
'/1/a': [
{ id: '/1/a/I',
title: 'I'
}
]
}
/*
* This saga `take`s the RETRIEVE_NODE action, then executes in order:
* 1. Changing the URL with the redux simple router `routeActions.push` method
* 2. Request a list of nodes from the server
* 3. Once the nodes are back call `show` a custom action that will reduce the state with new nodes
*/
export function* retrieveNode() {
let action = null
while(action = yield take('RETRIEVE_NODE')) {
yield put(routeActions.push(action.payload.nodeId))
let nodes = yield call(fetchNodes, action.payload.nodeId)
yield put(show(nodes))
}
}
/*
* This saga `take`s the UPDATE_LOCATION action, then checks if the update is a push or a pop.
* A pop means hiting the back/forward button, in this case -and only in this case- I want to
* retrieve new nodes, this will put a RETRIEVE_NODE andthat will be handled by the previous saga.
*/
export function* urlChanged() {
let action = null
while(action = yield take(UPDATE_LOCATION)) {
if(action.location.action === 'POP') {
yield put(retrieve(action.location.pathname))
}
}
}
function fetchNodes (nodeId) {
return new Promise(resolve =>
setTimeout( () => resolve(fakeDB[nodeId]), 1000 )
)
}
export default function* root() {
yield fork(retrieveNode)
yield fork(urlChanged)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment