Created
February 3, 2017 10:10
-
-
Save pie6k/c61c71e6c232c7356169afec8c7cd0ad to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// useage of screating asyncAction | |
// first argument is Promise provider - it needs to return some promise that will be resolved | |
// 2nd argument is function that will change the state. This function is called 2 times - 1. when action is called, 2. when promise is resolved or rejected | |
// 1st argument of this function is current state and 2nd argument is data in a form: | |
// {loading: true/false, data: undefined/promiseResult, error: false/promiseError} | |
export const getPostComments = createAsyncAction((postId) => { | |
return someApi.getPostCommentsPromise(postId); | |
}, (state, payload, postId) => { | |
// postId is just argument passed | |
payload.loading; // if promise is resolved or not | |
payload.error; // if promise is rejected | |
payload.data; // when promise is resolved - it'll be eg. array of comments | |
return state.doSomethingWithState(); | |
}); | |
// and later in component | |
<Button onClick={getPostComments(329)} /> | |
// implementation of redux-act helpers from above | |
import { createStore } from 'redux'; | |
import { createAction as createActionAct, createReducer } from 'redux-act'; | |
import Immutable, { Map, List } from 'immutable'; | |
import initial from './initial'; | |
export const reducer = createReducer(); | |
export const store = createStore(reducer, initial); | |
console.log(store); | |
window.store = store; | |
export function createAction(reducerFunc, description = undefined) { | |
const action = createActionAct(description, (arg = undefined) => { | |
if (!Map.isMap(arg)) return arg; | |
return arg.delete('_args'); | |
}, (arg = undefined) => { | |
if (!Map.isMap(arg)) return arg; | |
return arg.get('_args', List()).toJS(); | |
}).assignTo(store); | |
reducer.on(action, reducerFunc); | |
return action; | |
} | |
export function createAsyncAction(promiseSupplier, reducerFunc, timeout = 10000) { | |
const action = createAction(reducerFunc); | |
return (...args) => { | |
const promise = promiseSupplier.apply(store.getState(), args); | |
if (promise === true) return new Promise(resolve => resolve(store.getState())); | |
action(Immutable.fromJS({ | |
loading: true, | |
error: false, | |
data: undefined, | |
_args: args, | |
}), ...args); | |
const timeoutId = parseInt(timeout, 10) ? setTimeout(() => { | |
action(Immutable.fromJS({ | |
loading: false, | |
timeout: true, | |
error: false, | |
data: undefined, | |
_args: args, | |
}), ...args); | |
}, parseInt(timeout, 10)) : false; | |
return new Promise((resolve, reject) => { | |
promise.then((data) => { | |
clearTimeout(timeoutId); | |
action(Immutable.fromJS({ | |
loading: false, | |
loaded: true, | |
error: false, | |
data, | |
_args: args, | |
}), ...args); | |
resolve(store.getState()); | |
}).catch((error) => { | |
console.log(error); | |
clearTimeout(timeoutId); | |
action(Immutable.fromJS({ | |
loading: false, | |
data: undefined, | |
error, | |
_args: args, | |
}), ...args); | |
reject(error, store.getState()); | |
}); | |
}); | |
}; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment