-
Notifications
You must be signed in to change notification settings - Fork 9
Open
Description
Required:
somehow inside of controller without a lot of boilerplate code to get next: at begin of method dispatch action with promise for promise-middleware, that will be resolved/rejected at the end of method.
Recap:
- at begin of method set some redux state to true
- at end of method set same redux state to false
- at error do same as at (2)
In most cases it's common loading flag (e.g. API requests) to make UI to response changes of state (e.g. block/unblock controls).
Right now I'm doing it like this, but not sure that it's good way, maybe I miss something:
helper:
const blocking = (type, method, dispatch) => (...args) => {
return dispatch({ type, payload: new Promise((resolve, reject) => {
try {
resolve(method(...args));
} catch (e) {
reject(e);
}
})});
};generators with marked onLogin as blocking:
const generators = {
*initialize() {
const { dispatch } = yield getProps;
this.onLogin = blocking(types.APP_PREFIX, this.onLogin, dispatch);
yield this.userInfo(true, '/');
},
*onSiderCollapse() {
const { dispatch } = yield getProps;
dispatch(actions.siderCollapse());
},
*onLogin(params) {
const { dispatch } = yield getProps;
try {
yield api.login(params);
yield this.userInfo(false, '/');
} catch(e) {
dispatch(error(e)),
dispatch(auth.reset());
}
},
*onLogout() {
const { dispatch } = yield getProps;
try {
yield api.logout();
} catch(e) {
}
dispatch(auth.reset());
dispatch(navigate('/'));
},
*userInfo(silent = false, returnUrl) {
const { dispatch, route } = yield getProps;
try {
dispatch(auth.request());
const identity = yield api.fetchCurrrentUser();
dispatch(auth.receive(identity));
//if route has url to return, then use it
let redirect = route && route.query && route.query.return;
if(!redirect) {
redirect = returnUrl;
}
if(redirect) {
dispatch(navigate(redirect));
}
} catch(e) {
console.log(e);
if(!silent) {
dispatch(error(e));
}
dispatch(auth.reset());
dispatch(navigate('/'));
}
}
};I need it for my reducer, e.g.:
import typeToReducer from 'type-to-reducer';
import * as loading from '../../utils/loading';
import types from './actions';
const initialState = {
checking: false,
siderCollapsed: false,
};
const app = typeToReducer({
[types.SIDER_COLLAPSE]: (state, action) => ({ ...state, siderCollapsed: !state.siderCollapsed }),
[types.APP_PREFIX]: loading.reducers('checking'),
}, initialState);
export default app;utils is like this:
export const promiseTypeSuffixes = ['pending', 'fulfilled', 'rejected'];
export const reducers = (key, suffixes = promiseTypeSuffixes) => {
const reducers = { };
suffixes.forEach((suffix, i) => reducers[suffix] = (state, action) => ({ ...state, [key]: !i }));
return reducers;
};Metadata
Metadata
Assignees
Labels
No labels