React-Admin <ImageInput> to upload images to rails api

醉酒当歌 提交于 2020-01-24 18:50:53

问题


I am trying to upload images from react-admin to rails api backend using active storage.

In the documentation of react-admin it says: "Note that the image upload returns a File object. It is your responsibility to handle it depending on your API behavior. You can for instance encode it in base64, or send it as a multi-part form data" I am trying to send it as a multi-part form.

I have been reading here and there but I can not find what I want, at least a roadmap of how I should proceed.


回答1:


You can actually find an example in the dataProvider section of the documentation.

You have to decorate your dataProvider to enable the data upload. Here is the example of transforming the images into base64 strings before posting the resource:

// in addUploadFeature.js
/**
 * Convert a `File` object returned by the upload input into a base 64 string.
 * That's not the most optimized way to store images in production, but it's
 * enough to illustrate the idea of data provider decoration.
 */
const convertFileToBase64 = file => new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.readAsDataURL(file.rawFile);

    reader.onload = () => resolve(reader.result);
    reader.onerror = reject;
});

/**
 * For posts update only, convert uploaded image in base 64 and attach it to
 * the `picture` sent property, with `src` and `title` attributes.
 */
const addUploadFeature = requestHandler => (type, resource, params) => {
    if (type === 'UPDATE' && resource === 'posts') {
        // notice that following condition can be true only when `<ImageInput source="pictures" />` component has parameter `multiple={true}`
        // if parameter `multiple` is false, then data.pictures is not an array, but single object
        if (params.data.pictures && params.data.pictures.length) {
            // only freshly dropped pictures are instance of File
            const formerPictures = params.data.pictures.filter(p => !(p.rawFile instanceof File));
            const newPictures = params.data.pictures.filter(p => p.rawFile instanceof File);

            return Promise.all(newPictures.map(convertFileToBase64))
                .then(base64Pictures => base64Pictures.map((picture64, index) => ({
                    src: picture64,
                    title: `${newPictures[index].title}`,
                })))
                .then(transformedNewPictures => requestHandler(type, resource, {
                    ...params,
                    data: {
                        ...params.data,
                        pictures: [...transformedNewPictures, ...formerPictures],
                    },
                }));
        }
    }
    // for other request types and resources, fall back to the default request handler
    return requestHandler(type, resource, params);
};

export default addUploadFeature;

You can then apply this on your dataProvider:

// in dataProvider.js
import simpleRestProvider from 'ra-data-simple-rest';
import addUploadFeature from './addUploadFeature';

const dataProvider = simpleRestProvider('http://path.to.my.api/');
const uploadCapableDataProvider = addUploadFeature(dataProvider);

export default uploadCapableDataProvider;

Finally, you can use it in your admin as usual:

// in App.js
import { Admin, Resource } from 'react-admin';

import dataProvider from './dataProvider';
import PostList from './posts/PostList';

const App = () => (
    <Admin dataProvider={uploadCapableDataProvider}>
        <Resource name="posts" list={PostList} />
    </Admin>
);


来源:https://stackoverflow.com/questions/54202340/react-admin-imageinput-to-upload-images-to-rails-api

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!