Reputation: 1866
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:
Thanks in advance!
Upvotes: 3
Views: 10333
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
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
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