Last active
February 29, 2016 11:27
-
-
Save 2j2e/ed88c8767c69f06586b0 to your computer and use it in GitHub Desktop.
AltJS async action & store enhancers
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
const asyncAction = (target, action, descriptor) => { | |
// Define async handler action names | |
let actionBegin = action + 'Begin'; | |
let actionEnd = action + 'End'; | |
let actionFailure = action + 'Failure'; | |
// Action should explicitly call dispatch | |
let actionFunc = x => dispatch => dispatch(x); | |
// Async handlers methods | |
target[actionBegin] = actionFunc; | |
target[actionEnd] = actionFunc; | |
target[actionFailure] = actionFunc; | |
// Action wrapper | |
const wrapper = function () { | |
let args = arguments; | |
return (dispatch) => { | |
this[actionBegin](); | |
let response; | |
// Run parent action promise and handle it in appropriate way | |
return descriptor.value.apply(this, args) | |
.then(res => { | |
response = res; | |
return res.json(); | |
}) | |
.then(json => { | |
if (response.ok) { | |
dispatch(json); | |
} else { | |
// handle server side error (validation, etc.) | |
let issue = { | |
generalErrors: json.__all__, | |
errors: json.errors | |
}; | |
this[actionFailure](issue); | |
} | |
this[actionEnd](); | |
return response; | |
}, () => { | |
// handle unexpected error (network, etc.) | |
response.text() | |
.then(text => { | |
let issue = { | |
generalErrors: [text] | |
}; | |
this[actionFailure](issue); | |
this[actionEnd](); | |
}); | |
return response; | |
}); | |
} | |
}; | |
// Replace method with wrapper | |
return Object.assign({}, descriptor, {value: wrapper}); | |
}; | |
export default asyncAction; |
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
const asyncStoreEnhancer = (Store, ActionsClass, actions) => { | |
class AsyncStore extends Store { | |
constructor(...args) { | |
super(...args); | |
this.state = this.state || {}; | |
this.state.aux = {}; | |
this.bindListeners(listeners); | |
this.exportPublicMethods(publicMethods); | |
} | |
} | |
let listeners = {}; | |
let publicMethods = {}; | |
// Supported async actions | |
let postFixes = ['Begin', 'Failure', 'End']; | |
actions.forEach(action => { | |
postFixes.forEach(postfix => { | |
// Camel case action name | |
let capitilizedAction = action.charAt(0).toUpperCase() + action.slice(1); | |
// Handler name (onLoadBegin) | |
let handlerName = `on${capitilizedAction}${postfix}`; | |
// Source action name (loadBegin) | |
let actionName = `${action}${postfix}`; | |
if (postfix == 'Begin') { | |
AsyncStore.prototype[handlerName] = function () { | |
this.setState({ | |
aux: {[action]: {isFetching: true}} | |
}) | |
}; | |
} | |
if (postfix == 'End') { | |
AsyncStore.prototype[handlerName] = function () { | |
this.setState({ | |
aux: {[action]: {isFetching: false}} | |
}) | |
}; | |
} | |
if (postfix == 'Failure') { | |
AsyncStore.prototype[handlerName] = function () { | |
this.setState({ | |
aux: {[action]: {isFetching: false}} | |
}) | |
}; | |
} | |
listeners[handlerName] = ActionsClass[actionName]; | |
// fetching method helper like isLoadFetching() | |
publicMethods[`is${capitilizedAction}Fetching`] = function () { | |
return this.getState().aux && this.getState().aux[action] && this.getState().aux[action].isFetching; | |
} | |
}) | |
}); | |
return AsyncStore; | |
} | |
export default asyncStoreEnhancer; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment