Skip to content

Instantly share code, notes, and snippets.

@pie6k
Created February 3, 2017 10:10
Show Gist options
  • Save pie6k/c61c71e6c232c7356169afec8c7cd0ad to your computer and use it in GitHub Desktop.
Save pie6k/c61c71e6c232c7356169afec8c7cd0ad to your computer and use it in GitHub Desktop.
// 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