diff --git a/src/containers/Home/__tests__/action.test.js b/src/containers/Home/__tests__/action.test.js index 0658e0cf..2169b55a 100644 --- a/src/containers/Home/__tests__/action.test.js +++ b/src/containers/Home/__tests__/action.test.js @@ -10,13 +10,14 @@ import { USERS_FAILURE, USERS_SUCCESS, } from '../action'; +import promisedMiddleware from '../../../redux/promisedMiddleware'; const host = 'http://localhost'; axios.defaults.host = host; axios.defaults.adapter = httpAdapter; -const mockStore = configureMockStore([thunk]); +const mockStore = configureMockStore([thunk, promisedMiddleware(axios)]); describe('fetch users data', () => { const response = [{ id: '1', name: 'Welly' }]; diff --git a/src/containers/Home/action.js b/src/containers/Home/action.js index 1a3b3521..73580b33 100644 --- a/src/containers/Home/action.js +++ b/src/containers/Home/action.js @@ -15,18 +15,10 @@ export const USERS_SUCCESS = 'USERS_SUCCESS'; export const API_URL = 'https://jsonplaceholder.typicode.com/users'; // Export this for unit testing more easily -export const fetchUsers = (axios: any, URL: string = API_URL): ThunkAction => - (dispatch: Dispatch) => { - dispatch({ type: USERS_REQUESTING }); - - return axios.get(URL) - .then((res) => { - dispatch({ type: USERS_SUCCESS, data: res.data }); - }) - .catch((err) => { - dispatch({ type: USERS_FAILURE, err }); - }); - }; +export const fetchUsers = (axios: any, URL: string = API_URL): ThunkAction => ({ + promise: client => client.get(URL).then(value => ({ data: value.data })), + events: [USERS_REQUESTING, USERS_SUCCESS, USERS_FAILURE], +}); // Preventing dobule fetching data /* istanbul ignore next */ diff --git a/src/containers/UserInfo/__tests__/action.test.js b/src/containers/UserInfo/__tests__/action.test.js index 934f9747..868b5f11 100644 --- a/src/containers/UserInfo/__tests__/action.test.js +++ b/src/containers/UserInfo/__tests__/action.test.js @@ -10,13 +10,14 @@ import { USER_FAILURE, USER_SUCCESS, } from '../action'; +import promisedMiddleware from '../../../redux/promisedMiddleware'; const host = 'http://localhost'; axios.defaults.host = host; axios.defaults.adapter = httpAdapter; -const mockStore = configureMockStore([thunk]); +const mockStore = configureMockStore([thunk, promisedMiddleware(axios)]); describe('fetch user data', () => { const userId = 'test'; diff --git a/src/containers/UserInfo/action.js b/src/containers/UserInfo/action.js index 69e6b6ed..4aefee76 100644 --- a/src/containers/UserInfo/action.js +++ b/src/containers/UserInfo/action.js @@ -14,18 +14,11 @@ export const USER_SUCCESS = 'USER_SUCCESS'; export const API_URL = 'https://jsonplaceholder.typicode.com/users'; // Export this for unit testing more easily -export const fetchUser = (userId: string, axios: any, URL: string = API_URL): ThunkAction => - (dispatch: Dispatch) => { - dispatch({ type: USER_REQUESTING, userId }); - - return axios.get(`${URL}/${userId}`) - .then((res) => { - dispatch({ type: USER_SUCCESS, userId, data: res.data }); - }) - .catch((err) => { - dispatch({ type: USER_FAILURE, userId, err }); - }); - }; +export const fetchUser = (userId: string, axios: any, URL: string = API_URL): ThunkAction => ({ + promise: client => client.get(`${URL}/${userId}`).then(value => ({ data: value.data })), + events: [USER_REQUESTING, USER_SUCCESS, USER_FAILURE], + userId, +}); // Using for preventing dobule fetching data /* istanbul ignore next */ diff --git a/src/redux/promisedMiddleware.js b/src/redux/promisedMiddleware.js new file mode 100644 index 00000000..274fc99d --- /dev/null +++ b/src/redux/promisedMiddleware.js @@ -0,0 +1,17 @@ +export default (...args) => ({ dispatch, getState }) => next => (action) => { + if (typeof action === 'function') { + return action(dispatch, getState); + } + const { promise, events, ...rest } = action; + if (!promise) { + return next(action); + } + const [REQUEST, SUCCESS, FAILURE] = events; + next({ ...rest, type: REQUEST }); + return promise(...args).then( + value => next({ ...rest, ...value, type: SUCCESS }), + err => next({ ...rest, err, type: FAILURE }), + ).catch((err) => { + next({ ...rest, err, type: FAILURE }); + }); +}; diff --git a/src/redux/store.js b/src/redux/store.js index ac6b18f1..a034742f 100644 --- a/src/redux/store.js +++ b/src/redux/store.js @@ -8,11 +8,13 @@ import chalk from 'chalk'; import type { Store } from '../types'; import rootReducer from './reducers'; +import promisedMiddleware from './promisedMiddleware'; export default (history: Object, initialState: Object = {}): Store => { const middlewares = [ thunk.withExtraArgument(axios), routerMiddleware(history), + promisedMiddleware(axios), ]; const enhancers = [