oz19
oz19

Reputation: 1866

React-Admin | Cannot upload a file using FileInput

First time with React-Admin. I am using it to create a panel that basically monitors some parameters that I get from an API. However, one section requires a .csv file to be uploaded. I am trying to implement it with FileInput but I am unable to catch the file. I don't understand how to do it.

File selection step (from pc to browser) is working properly, but my problem is that I cannot handle the file after that step. I read the docs, but I don't know how to do it. I tried many different ways but I am getting crazy.

Below is the basic code. I guess I have to add a handler or something similar but, how? I have little experience with React too. I know the basics, but I just built a couple of (super) simple apps. Just for learn.

// UploadFile.js
...

export const UploadSection = props => (
    <SimpleForm>
        <FileInput source="csvFile" label="Upload file (.csv)" accept="text/csv" >
            <FileField source="src" title="title" />
        </FileInput>
    </SimpleForm>
);


// App.js
...

const App = () => (
    <Admin dataProvider={dataProvider} authProvider={authProvider} >
        ...
        <Resource name="uploadSection" list={UploadSection} />
        ...
    </Admin>
);

The question:

  1. How can I catch the .csv file?

Thanks in advance!

Upvotes: 3

Views: 10333

Answers (3)

selens
selens

Reputation: 427

Have you checked the DataProvider and UploadFeature sections in the documentation? If you have your own DataProvider, you can create a new file addUploadFeature.js and customize it as in the sample under this link:

https://marmelab.com/react-admin/DataProviders.html#extending-a-data-provider-example-of-file-upload

Upvotes: 0

oz19
oz19

Reputation: 1866

After working on it during hours I got it working.

First problem (the one I commented @selens answer): I got Uncaught TypeError: _this.props.save is not a function because I wasn't working in Create or Edit View. It seems you need to use FileInput in Create or Edit Views. If not, Save button won't work.

From docs:

save: The function invoked when the form is submitted. This is passed automatically by react-admin when the form component is used inside Create and Edit components.

Second problem: In my case I upload one file at a time (multiple={false} in FileInput). However, the code addUploadFeature.js is ready to use with multiple files. So, I edited part of addUploadFeature.js to upload just one file. See the complete file below.

// addUploadFeature.js

const convertFileToBase64 = file => new Promise((resolve, reject) => {
  const reader = new FileReader();
  reader.readAsDataURL(file.rawFile);

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

const addUploadFeature = requestHandler => (type, resource, params) => {

  if (type === 'UPDATE' && resource === 'myResource') {
  
      if (params.data.myFile) {

          // NEW CODE HERE (to upload just one file):
          const myFile = params.data.myFile;
          if ( !myFile.rawFile instanceof File ){
              return Promise.reject('Error: Not a file...'); // Didn't test this...
          }

          return Promise.resolve( convertFileToBase64(myFile) )
              .then( (picture64) => ({
                  src: picture64,
                  title: `${myFile.title}`
              }))
              .then( transformedMyFile => requestHandler(type, resource, {
                  ...params,
                  data: {
                      ...params.data,
                      myFile: transformedMyFile
                  }
              }));
      }
  }
  return requestHandler(type, resource, params);
};

export default addUploadFeature;

After all, I was able to send the file to the server in Base64 format.

Hope this to be useful for somebody in the future ;)

Upvotes: 7

Orest Borovets
Orest Borovets

Reputation: 106

I have a similar problem, I cannot upload a file and issue will be in accept prop.

You can use the following code:

<FileInput source="csvFile" label="Upload file (.csv)" accept=".csv" >

Instead of:

<FileInput source="csvFile" label="Upload file (.csv)" accept="text/csv" >

Upvotes: 1

Related Questions