diff --git a/src/components/courses/CoursesPage.js b/src/components/courses/CoursesPage.js index 6e73725..973cfd2 100644 --- a/src/components/courses/CoursesPage.js +++ b/src/components/courses/CoursesPage.js @@ -87,7 +87,7 @@ function mapStateToProps(state) { }; }), authors: state.authors, - loading: state.apiCallsInProgress > 0 + loading: state.ajaxCallsInProgress > 0 }; } diff --git a/src/features/system/actionCreators.js b/src/features/system/actionCreators.js index a1de755..cb303d3 100644 --- a/src/features/system/actionCreators.js +++ b/src/features/system/actionCreators.js @@ -1,18 +1,13 @@ import * as types from "./actionTypes"; import api from "./api"; -import { - beginApiCall, - apiCallError -} from "../../redux/actions/apiStatusActions"; +import { sendHttpRequest } from "../../redux/actions/httpActions"; export function loadSystemDateTime() { return async function (dispatch) { - dispatch(beginApiCall()); try { - const data = await api.getSystemDateTime(); + const data = await dispatch(sendHttpRequest(api.getSystemDateTime())); dispatch({ type: types.LOAD_SYSTEM_DATETIME_SUCCESS, payload: data }); } catch (error) { - dispatch(apiCallError(error)); throw error; } }; @@ -20,12 +15,10 @@ export function loadSystemDateTime() { export function loadSystemVersion() { return async function (dispatch) { - dispatch(beginApiCall()); try { - const data = await api.getSystemVersion(); + const data = await dispatch(sendHttpRequest(api.getSystemVersion())); dispatch({ type: types.LOAD_SYSTEM_VERSION_SUCCESS, payload: data }); } catch (error) { - dispatch(apiCallError(error)); throw error; } }; @@ -33,12 +26,10 @@ export function loadSystemVersion() { export function loadReleaseNotes() { return async function (dispatch) { - dispatch(beginApiCall()); try { - const data = await api.getReleaseNotes(); + const data = await dispatch(sendHttpRequest(api.getReleaseNotes())); dispatch({ type: types.LOAD_RELEASE_NOTES_SUCCESS, payload: data }); } catch (error) { - dispatch(apiCallError(error)); throw error; } }; diff --git a/src/redux/actions/actionTypes.js b/src/redux/actions/actionTypes.js index 612614e..dde65a7 100644 --- a/src/redux/actions/actionTypes.js +++ b/src/redux/actions/actionTypes.js @@ -3,8 +3,6 @@ export const LOAD_COURSES_SUCCESS = "LOAD_COURSES_SUCCESS"; export const LOAD_AUTHORS_SUCCESS = "LOAD_AUTHORS_SUCCESS"; export const CREATE_COURSE_SUCCESS = "CREATE_COURSE_SUCCESS"; export const UPDATE_COURSE_SUCCESS = "UPDATE_COURSE_SUCCESS"; -export const BEGIN_API_CALL = "BEGIN_API_CALL"; -export const API_CALL_ERROR = "API_CALL_ERROR"; // By convention, actions that end in "_SUCCESS" are assumed to have been the result of a completed // API call. But since we're doing an optimistic delete, we're hiding loading state. @@ -12,3 +10,7 @@ export const API_CALL_ERROR = "API_CALL_ERROR"; // If it had one, our apiCallsInProgress counter would be decremented below zero // because we're not incrementing the number of apiCallInProgress when the delete request begins. export const DELETE_COURSE_OPTIMISTIC = "DELETE_COURSE_OPTIMISTIC"; + +export const BEGIN_AJAX_CALL = "BEGIN_AJAX_CALL"; +export const AJAX_CALL_ERROR = "AJAX_CALL_ERROR"; +export const END_AJAX_CALL = "END_AJAX_CALL"; diff --git a/src/redux/actions/apiStatusActions.js b/src/redux/actions/apiStatusActions.js deleted file mode 100644 index 743d91a..0000000 --- a/src/redux/actions/apiStatusActions.js +++ /dev/null @@ -1,9 +0,0 @@ -import * as types from "./actionTypes"; - -export function beginApiCall() { - return { type: types.BEGIN_API_CALL }; -} - -export function apiCallError() { - return { type: types.API_CALL_ERROR }; -} diff --git a/src/redux/actions/authorActions.js b/src/redux/actions/authorActions.js index a636086..0e49bfc 100644 --- a/src/redux/actions/authorActions.js +++ b/src/redux/actions/authorActions.js @@ -1,22 +1,18 @@ import * as types from "./actionTypes"; import * as authorApi from "../../api/authorApi"; -import { beginApiCall, apiCallError } from "./apiStatusActions"; +import { sendHttpRequest } from "../actions/httpActions"; function loadAuthorsSuccess(authors) { return { type: types.LOAD_AUTHORS_SUCCESS, authors }; } export function loadAuthors() { - return function (dispatch) { - dispatch(beginApiCall()); - return authorApi - .getAuthors() - .then((authors) => { - dispatch(loadAuthorsSuccess(authors)); - }) - .catch((error) => { - dispatch(apiCallError(error)); - throw error; - }); + return async function (dispatch) { + try { + const authors = await dispatch(sendHttpRequest(authorApi.getAuthors())); + dispatch(loadAuthorsSuccess(authors)); + } catch (error) { + throw error; + } }; } diff --git a/src/redux/actions/courseActions.js b/src/redux/actions/courseActions.js index b59760c..59278c9 100644 --- a/src/redux/actions/courseActions.js +++ b/src/redux/actions/courseActions.js @@ -1,6 +1,6 @@ import * as types from "./actionTypes"; import * as courseApi from "../../api/courseApi"; -import { beginApiCall, apiCallError } from "./apiStatusActions"; +import { sendHttpRequest } from "../actions/httpActions"; function loadCoursesSuccess(courses) { return { type: types.LOAD_COURSES_SUCCESS, courses }; @@ -20,14 +20,11 @@ export function deleteCourseOptimistic(course) { export function loadCourses() { return function (dispatch) { - dispatch(beginApiCall()); - return courseApi - .getCourses() + return dispatch(sendHttpRequest(courseApi.getCourses())) .then((courses) => { dispatch(loadCoursesSuccess(courses)); }) .catch((error) => { - dispatch(apiCallError(error)); throw error; }); }; @@ -36,16 +33,13 @@ export function loadCourses() { export function saveCourse(course) { //eslint-disable-next-line no-unused-vars return function (dispatch, getState) { - dispatch(beginApiCall()); - return courseApi - .saveCourse(course) + return dispatch(sendHttpRequest(courseApi.saveCourse(course))) .then((savedCourse) => { course.id ? dispatch(updateCourseSuccess(savedCourse)) : dispatch(createCourseSuccess(savedCourse)); }) .catch((error) => { - dispatch(apiCallError(error)); throw error; }); }; diff --git a/src/redux/actions/httpActions.js b/src/redux/actions/httpActions.js new file mode 100644 index 0000000..5fb746a --- /dev/null +++ b/src/redux/actions/httpActions.js @@ -0,0 +1,27 @@ +import * as types from "./actionTypes"; + +function beginAjaxCall() { + return { type: types.BEGIN_AJAX_CALL }; +} + +function ajaxCallError() { + return { type: types.AJAX_CALL_ERROR }; +} + +function endAjaxCall() { + return { type: types.END_AJAX_CALL }; +} + +export function sendHttpRequest(ajaxProm) { + return async (dispatch) => { + dispatch(beginAjaxCall()); + try { + const result = await ajaxProm; + dispatch(endAjaxCall()); + return result; + } catch (error) { + dispatch(ajaxCallError(error)); + throw error; + } + }; +} diff --git a/src/redux/reducers/ajaxStatusReducer.js b/src/redux/reducers/ajaxStatusReducer.js new file mode 100644 index 0000000..c19c85a --- /dev/null +++ b/src/redux/reducers/ajaxStatusReducer.js @@ -0,0 +1,18 @@ +import * as types from "../actions/actionTypes"; +import initialState from "./initialState"; + +export default function ajaxStatusReducer( + state = initialState.ajaxCallsInProgress, + action +) { + if (action.type === types.BEGIN_AJAX_CALL) { + return state + 1; + } else if ( + action.type === types.AJAX_CALL_ERROR || + action.type === types.END_AJAX_CALL + ) { + return state - 1; + } + + return state; +} diff --git a/src/redux/reducers/apiStatusReducer.js b/src/redux/reducers/apiStatusReducer.js deleted file mode 100644 index 3755957..0000000 --- a/src/redux/reducers/apiStatusReducer.js +++ /dev/null @@ -1,22 +0,0 @@ -import * as types from "../actions/actionTypes"; -import initialState from "./initialState"; - -function actionTypeEndsInSuccess(type) { - return type.substring(type.length - 8) === "_SUCCESS"; -} - -export default function apiCallStatusReducer( - state = initialState.apiCallsInProgress, - action -) { - if (action.type == types.BEGIN_API_CALL) { - return state + 1; - } else if ( - action.type == types.API_CALL_ERROR || - actionTypeEndsInSuccess(action.type) - ) { - return state - 1; - } - - return state; -} diff --git a/src/redux/reducers/index.js b/src/redux/reducers/index.js index 070debc..51a78bb 100644 --- a/src/redux/reducers/index.js +++ b/src/redux/reducers/index.js @@ -1,14 +1,14 @@ import { combineReducers } from "redux"; import courseReducer from "./courseReducer"; import authorReducer from "./authorReducer"; -import apiStatusReducer from "./apiStatusReducer"; +import ajaxStatusReducer from "./ajaxStatusReducer"; import systemReducer from "../../features/system/reducer"; const rootReducer = combineReducers({ system: systemReducer, courses: courseReducer, authors: authorReducer, - apiCallsInProgress: apiStatusReducer + ajaxCallsInProgress: ajaxStatusReducer }); export default rootReducer; diff --git a/src/redux/reducers/initialState.js b/src/redux/reducers/initialState.js index c6baead..df40f15 100644 --- a/src/redux/reducers/initialState.js +++ b/src/redux/reducers/initialState.js @@ -2,5 +2,5 @@ export default { system: {}, courses: [], authors: [], - apiCallsInProgress: 0 + ajaxCallsInProgress: 0 };