/* eslint-disable */
/**
* Axios Request Wrapper
* ---------------------
* wraps arouund axios and redux
*/
/////////////////////
// USAGE
/////////////////////
// import request from 'utils/request';
//
// Simple Usage
// --------------------
// request({
// action: 'OFFER',
// method: 'get',
// url: '/path/offer'
// }).then((resp) => {
// console.log(resp);
// })
//
import axios from 'axios';
import { store } from 'app.js';
import tracker from './requestTracker';
/**
* Redux
*/
export const SUCCESS_SUFFIX = '_SUCCESS';
export const FAILURE_SUFFIX = '_FAILURE';
export const REQUEST_SUFFIX = '_REQUEST';
export const DEFAULTACTION_NAME = 'API';
// use it in redcer
export function getActionType(action) {
if (!action) return {};
return {
REQUEST: `${action}${REQUEST_SUFFIX}`.toUpperCase(),
SUCCESS: `${action}${SUCCESS_SUFFIX}`.toUpperCase(),
FAILURE: `${action}${FAILURE_SUFFIX}`.toUpperCase(),
};
}
function withStore(type, payload) {
return type ? store.dispatch({ type, payload }) : null;
}
/**
* Request Wrapper with default success/error actions
*/
export const client = axios.create({
baseURL: null,
});
const request = function(options) {
// Redux helper
const { action } = options;
let actions = getActionType(action);
tracker.set(action);
withStore(actions.REQUEST, true);
const onSuccess = function(response) {
withStore(actions.SUCCESS, response.data);
console.debug('Request Successful!', response);
return {
header: { status: response.status, statusText: response.statusText },
...response.data,
};
};
const onError = function(error) {
withStore(actions.FAILURE, { error: true, message: error.message });
console.error('Request Failed:', error.config);
if (error.response) {
// Request was made but server responded with something
// other than 2xx
console.error('Status:', error.response.status);
console.error('Data:', error.response.data);
console.error('Headers:', error.response.headers);
} else {
// Something else happened while setting up the request
// triggered the error
console.error('Error Message:', error.message);
}
return Promise.reject(error.response || error.message);
};
return client(options)
.then(onSuccess)
.catch(onError);
};
window.request = request; // for development mode
export default request;
import { getActionType } from './request';
export class RequestTracker {
reducers = new Set([]);
actions = new Set([]);
set = actionName => {
if (!actionName) return;
if (this.reducers.has(actionName)) return;
if (typeof actionName !== 'string') {
throw new Error('actionName must be string!');
}
this.reducers.add(actionName);
const actns = getActionType(actionName);
// structure
const o = {
actionName,
actions: actns,
};
this.actions.add(o);
};
get = actionName => {
const exists = this.reducers.filter(item => item === actionName).length;
const ans = this.actions.filter(item => item.actionName === actionName);
if (!exists) return undefined;
if (ans.length > 0) {
return ans[0].actions;
}
return undefined;
};
}
const tracker = new RequestTracker();
export default tracker;
/**
* A reducer that keeps track of ./request calls
*/
import tracker from './requestTracker';
const intialState = {};
export const requestReducer = (state = intialState, action) => {
const { type, payload } = action;
let newState = { ...state };
if (!tracker) return newState;
tracker.actions.forEach(actionGroup => {
const { actions, actionName } = actionGroup;
switch (type) {
case actions.REQUEST:
newState[actionName] = { request: payload };
break;
case actions.SUCCESS:
newState[actionName] = { data: payload, request: false };
break;
case actions.FAILURE:
newState[actionName] = { error: payload, request: false };
break;
default:
newState = { ...state };
}
});
return newState;
};
export default requestReducer;