Skip to content

Instantly share code, notes, and snippets.

@maruware
Created April 19, 2017 06:41
Show Gist options
  • Save maruware/edcf91e08f083e9354e431ad561b6f99 to your computer and use it in GitHub Desktop.
Save maruware/edcf91e08f083e9354e431ad561b6f99 to your computer and use it in GitHub Desktop.
File upload on admin-on-rest
const addUploadCapabilities = requestHandler => (type, resource, params) => {
if (type === 'UPDATE' && resource === 'posts') {
if (params.data.video) {
params.data.video = params.data.video[0]
}
}
return requestHandler(type, resource, params);
};
export default addUploadCapabilities;
import React from 'react';
import { Field } from 'redux-form';
const FileInput = (props) => (
<span>
<Field name={props.name} component="input" type="file" label={props.label} />
</span>
);
export default FileInput;
import { fetchUtils } from 'admin-on-rest';
const {queryParameters, fetchJson} = fetchUtils
import {
GET_LIST,
GET_ONE,
GET_MANY,
GET_MANY_REFERENCE,
CREATE,
UPDATE,
DELETE,
} from 'admin-on-rest';
export default (apiUrl, httpClient = fetchJson) => {
const convertRESTRequestToHTTP = (type, resource, params) => {
let url = '';
const options = {};
switch (type) {
case GET_LIST: {
const { page, perPage } = params.pagination;
const { field, order } = params.sort;
const query = {
sort: JSON.stringify([field, order]),
range: JSON.stringify([(page - 1) * perPage, (page * perPage) - 1]),
filter: JSON.stringify(params.filter),
};
url = `${apiUrl}/${resource}?${queryParameters(query)}`;
break;
}
case GET_ONE:
url = `${apiUrl}/${resource}/${params.id}`;
break;
case GET_MANY: {
const query = {
filter: JSON.stringify({ id: params.ids }),
};
url = `${apiUrl}/${resource}?${queryParameters(query)}`;
break;
}
case GET_MANY_REFERENCE: {
const { page, perPage } = params.pagination;
const { field, order } = params.sort;
const query = {
sort: JSON.stringify([field, order]),
range: JSON.stringify([(page - 1) * perPage, (page * perPage) - 1]),
filter: JSON.stringify({ ...params.filter, [params.target]: params.id }),
};
url = `${apiUrl}/${resource}?${queryParameters(query)}`;
break;
}
case UPDATE: {
url = `${apiUrl}/${resource}/${params.id}`;
options.method = 'PUT';
const fd = new FormData();
for (let key in params.data) {
fd.append(key, params.data[key])
}
options.body = fd;
break;
}
case CREATE: {
url = `${apiUrl}/${resource}`;
options.method = 'POST';
const fd = new FormData();
for (let key in params.data) {
fd.append(key, params.data[key])
}
options.body = fd;
break;
}
case DELETE:
url = `${apiUrl}/${resource}/${params.id}`;
options.method = 'DELETE';
break;
default:
throw new Error(`Unsupported fetch action type ${type}`);
}
return { url, options };
};
const convertHTTPResponseToREST = (response, type, resource, params) => {
const { headers, json } = response;
switch (type) {
case GET_LIST:
case GET_MANY_REFERENCE:
if (!headers.has('x-total-count')) {
throw new Error('The X-Total-Count header is missing in the HTTP Response. The jsonServer REST client expects responses for lists of resources to contain this header with the total number of results to build the pagination. If you are using CORS, did you declare X-Total-Count in the Access-Control-Expose-Headers header?');
}
return {
data: json,
total: parseInt(headers.get('x-total-count').split('/').pop(), 10),
};
case CREATE:
return { data: { ...params.data, id: json.id } };
default:
return { data: json };
}
};
/**
* @param {string} type Request type, e.g GET_LIST
* @param {string} resource Resource name, e.g. "posts"
* @param {Object} payload Request parameters. Depends on the request type
* @returns {Promise} the Promise for a REST response
*/
return (type, resource, params) => {
const { url, options } = convertRESTRequestToHTTP(type, resource, params);
return httpClient(url, options)
.then(response => convertHTTPResponseToREST(response, type, resource, params));
};
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment