Skip to content

Instantly share code, notes, and snippets.

@daino3
Last active October 7, 2024 04:52
Show Gist options
  • Select an option

  • Save daino3/3da80fe2a3c8f9411214044a7f5611b3 to your computer and use it in GitHub Desktop.

Select an option

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
Copy Markdown

This is awesome

@daino3
Copy link
Copy Markdown
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