http actions - sendHttpRequest

master
Tudor Stanciu 2020-05-06 22:03:52 +03:00
parent 0611020027
commit 3b7eede714
11 changed files with 68 additions and 71 deletions

View File

@ -87,7 +87,7 @@ function mapStateToProps(state) {
}; };
}), }),
authors: state.authors, authors: state.authors,
loading: state.apiCallsInProgress > 0 loading: state.ajaxCallsInProgress > 0
}; };
} }

View File

@ -1,18 +1,13 @@
import * as types from "./actionTypes"; import * as types from "./actionTypes";
import api from "./api"; import api from "./api";
import { import { sendHttpRequest } from "../../redux/actions/httpActions";
beginApiCall,
apiCallError
} from "../../redux/actions/apiStatusActions";
export function loadSystemDateTime() { export function loadSystemDateTime() {
return async function (dispatch) { return async function (dispatch) {
dispatch(beginApiCall());
try { try {
const data = await api.getSystemDateTime(); const data = await dispatch(sendHttpRequest(api.getSystemDateTime()));
dispatch({ type: types.LOAD_SYSTEM_DATETIME_SUCCESS, payload: data }); dispatch({ type: types.LOAD_SYSTEM_DATETIME_SUCCESS, payload: data });
} catch (error) { } catch (error) {
dispatch(apiCallError(error));
throw error; throw error;
} }
}; };
@ -20,12 +15,10 @@ export function loadSystemDateTime() {
export function loadSystemVersion() { export function loadSystemVersion() {
return async function (dispatch) { return async function (dispatch) {
dispatch(beginApiCall());
try { try {
const data = await api.getSystemVersion(); const data = await dispatch(sendHttpRequest(api.getSystemVersion()));
dispatch({ type: types.LOAD_SYSTEM_VERSION_SUCCESS, payload: data }); dispatch({ type: types.LOAD_SYSTEM_VERSION_SUCCESS, payload: data });
} catch (error) { } catch (error) {
dispatch(apiCallError(error));
throw error; throw error;
} }
}; };
@ -33,12 +26,10 @@ export function loadSystemVersion() {
export function loadReleaseNotes() { export function loadReleaseNotes() {
return async function (dispatch) { return async function (dispatch) {
dispatch(beginApiCall());
try { try {
const data = await api.getReleaseNotes(); const data = await dispatch(sendHttpRequest(api.getReleaseNotes()));
dispatch({ type: types.LOAD_RELEASE_NOTES_SUCCESS, payload: data }); dispatch({ type: types.LOAD_RELEASE_NOTES_SUCCESS, payload: data });
} catch (error) { } catch (error) {
dispatch(apiCallError(error));
throw error; throw error;
} }
}; };

View File

@ -3,8 +3,6 @@ export const LOAD_COURSES_SUCCESS = "LOAD_COURSES_SUCCESS";
export const LOAD_AUTHORS_SUCCESS = "LOAD_AUTHORS_SUCCESS"; export const LOAD_AUTHORS_SUCCESS = "LOAD_AUTHORS_SUCCESS";
export const CREATE_COURSE_SUCCESS = "CREATE_COURSE_SUCCESS"; export const CREATE_COURSE_SUCCESS = "CREATE_COURSE_SUCCESS";
export const UPDATE_COURSE_SUCCESS = "UPDATE_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 // 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. // 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 // 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. // because we're not incrementing the number of apiCallInProgress when the delete request begins.
export const DELETE_COURSE_OPTIMISTIC = "DELETE_COURSE_OPTIMISTIC"; 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";

View File

@ -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 };
}

View File

@ -1,22 +1,18 @@
import * as types from "./actionTypes"; import * as types from "./actionTypes";
import * as authorApi from "../../api/authorApi"; import * as authorApi from "../../api/authorApi";
import { beginApiCall, apiCallError } from "./apiStatusActions"; import { sendHttpRequest } from "../actions/httpActions";
function loadAuthorsSuccess(authors) { function loadAuthorsSuccess(authors) {
return { type: types.LOAD_AUTHORS_SUCCESS, authors }; return { type: types.LOAD_AUTHORS_SUCCESS, authors };
} }
export function loadAuthors() { export function loadAuthors() {
return function (dispatch) { return async function (dispatch) {
dispatch(beginApiCall()); try {
return authorApi const authors = await dispatch(sendHttpRequest(authorApi.getAuthors()));
.getAuthors()
.then((authors) => {
dispatch(loadAuthorsSuccess(authors)); dispatch(loadAuthorsSuccess(authors));
}) } catch (error) {
.catch((error) => {
dispatch(apiCallError(error));
throw error; throw error;
}); }
}; };
} }

View File

@ -1,6 +1,6 @@
import * as types from "./actionTypes"; import * as types from "./actionTypes";
import * as courseApi from "../../api/courseApi"; import * as courseApi from "../../api/courseApi";
import { beginApiCall, apiCallError } from "./apiStatusActions"; import { sendHttpRequest } from "../actions/httpActions";
function loadCoursesSuccess(courses) { function loadCoursesSuccess(courses) {
return { type: types.LOAD_COURSES_SUCCESS, courses }; return { type: types.LOAD_COURSES_SUCCESS, courses };
@ -20,14 +20,11 @@ export function deleteCourseOptimistic(course) {
export function loadCourses() { export function loadCourses() {
return function (dispatch) { return function (dispatch) {
dispatch(beginApiCall()); return dispatch(sendHttpRequest(courseApi.getCourses()))
return courseApi
.getCourses()
.then((courses) => { .then((courses) => {
dispatch(loadCoursesSuccess(courses)); dispatch(loadCoursesSuccess(courses));
}) })
.catch((error) => { .catch((error) => {
dispatch(apiCallError(error));
throw error; throw error;
}); });
}; };
@ -36,16 +33,13 @@ export function loadCourses() {
export function saveCourse(course) { export function saveCourse(course) {
//eslint-disable-next-line no-unused-vars //eslint-disable-next-line no-unused-vars
return function (dispatch, getState) { return function (dispatch, getState) {
dispatch(beginApiCall()); return dispatch(sendHttpRequest(courseApi.saveCourse(course)))
return courseApi
.saveCourse(course)
.then((savedCourse) => { .then((savedCourse) => {
course.id course.id
? dispatch(updateCourseSuccess(savedCourse)) ? dispatch(updateCourseSuccess(savedCourse))
: dispatch(createCourseSuccess(savedCourse)); : dispatch(createCourseSuccess(savedCourse));
}) })
.catch((error) => { .catch((error) => {
dispatch(apiCallError(error));
throw error; throw error;
}); });
}; };

View File

@ -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;
}
};
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -1,14 +1,14 @@
import { combineReducers } from "redux"; import { combineReducers } from "redux";
import courseReducer from "./courseReducer"; import courseReducer from "./courseReducer";
import authorReducer from "./authorReducer"; import authorReducer from "./authorReducer";
import apiStatusReducer from "./apiStatusReducer"; import ajaxStatusReducer from "./ajaxStatusReducer";
import systemReducer from "../../features/system/reducer"; import systemReducer from "../../features/system/reducer";
const rootReducer = combineReducers({ const rootReducer = combineReducers({
system: systemReducer, system: systemReducer,
courses: courseReducer, courses: courseReducer,
authors: authorReducer, authors: authorReducer,
apiCallsInProgress: apiStatusReducer ajaxCallsInProgress: ajaxStatusReducer
}); });
export default rootReducer; export default rootReducer;

View File

@ -2,5 +2,5 @@ export default {
system: {}, system: {},
courses: [], courses: [],
authors: [], authors: [],
apiCallsInProgress: 0 ajaxCallsInProgress: 0
}; };