Skip to content

Instantly share code, notes, and snippets.

@daino3
Last active June 10, 2022 15:04
Show Gist options
  • Star 9 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save daino3/3da80fe2a3c8f9411214044a7f5611b3 to your computer and use it in GitHub Desktop.
Save daino3/3da80fe2a3c8f9411214044a7f5611b3 to your computer and use it in GitHub Desktop.
import axios from 'axios';
import {toCamelCase, toSnakeCase} from '../util';
import qs from 'qs';
// You can intercept requests or responses before they are handled by then or catch.
// https://github.com/axios/axios#interceptors
// Add a response interceptor and camelCase return data (for JS)
axios.interceptors.response.use((response) => {
response.data = toCamelCase(response.data);
return response;
}, (error) => {
error.response.data = toCamelCase(error.response.data);
return Promise.reject(error);
});
// Add a request interceptor and snakeCase POST data (for django)
axios.interceptors.request.use((config) => {
config.params = toSnakeCase(config.params);
config.data = toSnakeCase(config.data);
return config;
}, (error) => {
return Promise.reject(error);
});
export default class Client {
__resource(url) {
return `${window.location.protocol}//${window.location.host}/${url}`
}
get(url, data, successCB, catchCB) {
return this.__perform('get', url, data, successCB, catchCB);
}
post(url, data, successCB, catchCB) {
return this.__perform('post', url, data, successCB, catchCB);
}
put(url, data, successCB, catchCB) {
return this.__perform('put', url, data, successCB, catchCB);
}
delete(url, data, successCB, catchCB) {
return this.__perform('delete', url, data, successCB, catchCB);
}
__getCSRFToken(name) {
let cookieValue = null;
if (document.cookie && document.cookie !== '') {
let cookies = document.cookie.split(';');
for (let i = 0; i < cookies.length; i++) {
let cookie = cookies[i].trim();
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
__perform(method, url, data, successCB, catchCB) {
const headers = {
'Content-Type': 'application/json',
'X-CSRFToken': this.__getCSRFToken('csrftoken'),
};
let params = null;
if (method.toLowerCase() === 'get' || method.toLowerCase() === 'delete') {
// If a GET or DELETE request
// These request types use 'params' not 'data'
params = {...data};
Object.freeze(params);
data = null;
}
const response = axios({
method: method,
url: this.__resource(url),
headers: headers,
params: params, // GET and DELETE requests have params
// remove array params bracket
paramsSerializer: (params) => {
return qs.stringify(params, {indices: false})
},
data: data, // POST and PUT requests have data
});
if (successCB || catchCB) {
return response.then(successCB).catch(catchCB);
}
return response;
}
}
import React, {Component} from 'react';
import Client from './client';
export default class Appointments extends Component {
constructor(props) {
super(props)
this.state = {
employees: [],
employee: {
name: 'Dain'
someLongAttribute: 'yadda yadda',
},
}
this.createEmployee = this.createEmployee.bind(this);
}
componentDidMount() {
// use the client by providing callbacks
Client.get('/api/v1/employees', {},
(response) => this.setState({employees: response.data}),
(response) => console.log(response),
);
}
createEmployee() {
// or don't provide callbacks and use the returned promise
const promise = Client.post('/api/v1/employees', this.state.employee)
promise.then(
(response) => this.setState({employees: [...this.state.employees, response.data]})
).catch(
(response) => console.log(response)
);
}
render() {
const employees = this.state.map(emp => <li>emp.someLongAttribute</li>);
return (
<div>
<ul>
{employees}
</ul>
<button onClick={this.createEmployee}>Create Employee!</button>
<div>
);
}
}
import _ from 'lodash';
function toCamelCase(object) {
let camelCaseObject = _.cloneDeep(object);
if (_.isArray(camelCaseObject)) {
return _.map(camelCaseObject, toCamelCase);
} else {
camelCaseObject = _.mapKeys(camelCaseObject, (value, key) => {
return _.camelCase(key);
});
// Recursively apply throughout object
return _.mapValues(camelCaseObject, (value) => {
if (_.isPlainObject(value)) {
return toCamelCase(value);
} else if (_.isArray(value)) {
return _.map(value, toCamelCase);
} else {
return value;
}
});
}
};
function toSnakeCase(object) {
let snakeCaseObject = _.cloneDeep(object);
if (_.isArray(snakeCaseObject)) {
return _.map(snakeCaseObject, toSnakeCase);
} else {
snakeCaseObject = _.mapKeys(snakeCaseObject, (value, key) => {
return _.snakeCase(key);
});
// Recursively apply throughout object
return _.mapValues(snakeCaseObject, (value) => {
if (_.isPlainObject(value)) {
return toSnakeCase(value);
} else if (_.isArray(value)) {
return _.map(value, toSnakeCase);
} else {
return value;
}
});
}
};
export {toCamelCase, toSnakeCase};
@naveedkakal
Copy link

This is awesome

@daino3
Copy link
Author

daino3 commented Nov 12, 2019

Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment