发出通过POST Axios& amp;将CSV文件提交到数据库的问题反应最终形式 [英] Issue to submit CSV file to DB via POST Axios & React-Final-Form
问题描述
我需要使用React-Final-Form和Axios将CSV的内容保存到数据库表中.
I need to save the content of a CSV into a database table by using React-Final-Form and Axios.
我试图在不使用Final-Form或Axios的情况下创建简单的HTML,并且向数据库的提交工作正常. 问题是当我尝试将CSV的内容传递给将处理POST调用的函数时. 参见下面的代码:
I have tried to create a simple HTML without using Final-Form or Axios and the submission to the DB works fine. The problem is when I try to pass the content of the CSV to a function which will handle the POST call. See code below:
import React, { Fragment } from "react";
import { Form, Field } from "react-final-form";
import createDecorators from "final-form-focus";
const handleSubmitOnClick = file => {
const url = 'http://localhost:3000/api/v1/invitations/upload';
const data = new FormData();
data.append('file', new File([file], { type: 'text/csv' }));
return axios.post(url, data, {
headers: {
'content-type': 'multipart/form-data'
}
})
.then(response => console.log(response))
.catch(error => console.log(error));
}
const JoinTesting = () =>
<Fragment>
<h1>Join Testing Page</h1>
<Form
onSubmit={handleSubmitOnClick}
decorators={[focusOnError]}
>
{
({
handleSubmit,
values,
submitting,
}) => (
<form onSubmit={handleSubmit} encType="multipart/form-data">
<Field
name='invitation[file]'
placeholder='Upload csv file'
validate={required}
>
{({ input, meta, placeholder }) => (
<div className={meta.active ? 'active' : ''}>
<label>{placeholder}</label>
<input {...input}
type='file'
placeholder={placeholder}
className="join-field-input"
/>
{meta.error && meta.touched && <span className="invalid">{meta.error}</span>}
{meta.valid && meta.dirty && <span className="valid">Great!</span>}
</div>
)}
</Field>
<button
type="submit"
className="join-button"
disabled={submitting}
>
Submit
</button>
<pre>{JSON.stringify(values, 0, 2)}</pre>
</form>
)}
</Form>
</Fragment>
export default JoinTesting;
如果我删除了上述所有内容,而只在JoinTesting组件中使用了此HTML,它就可以正常工作,但我无法处理错误(如果有的话)
If I remove ALL the above and I just use this HTML within my JoinTesting component, it works fine but I can't handle the errors (if any)
<form action="http://localhost:3000/api/v1/invitations/upload" method="post" encType="multipart/form-data">
Select CSV to upload:
<input type="file" name="invitation[file]" id="fileToUpload" />
<br></br>
<input type="submit" value="Upload CSV" name="submit" />
</form>
请注意:CSV文件只有一个简单的1列,其中包含一系列电子邮件地址. 这是POST请求所期望的:
PLEASE NOTE: The CSV file has only a simple 1 column with a sequence of email addresses. This is what the POST request expects:
标题:
Content-Type: application/json
Accept: application/json
身体
{
"invitation": {
"file": "Email\nuser_1@gmail.com\nuser_2@gmail.com\nuser_3@gmail.com\nuser_4@gmail.com\n"
}
}
成功调用的API响应为:
The API response expected for a success call is:
{
"success": true,
"emails": [
"user_1@gmail.com",
"user_2@gmail.com",
"user_3@gmail.com",
"user_4@gmail.com"
]
}
我希望有人可以提供帮助. 乔治
I hope someone can help. George
推荐答案
如果您不是不是使用html form
+ HTTP POST + encType="multipart/form-data"
您需要自己处理文件上传.
If you're not using html form
+ HTTP POST + encType="multipart/form-data"
, then you'll need to handle the file upload yourself.
一种方法:获取对input
组件的引用,侦听更改,发生更改时,从输入引用中获取文件名,读取文件,保存数据.这是用于此的组件:
One way to do it: get reference to the input
component, listen to changes, when a change happens get the filename from the input reference, read the file, save the data. Here's a component for that:
function FileInput(props) {
const fileInput = useRef(null);
const setRef = ref => {
fileInput.current = ref;
};
async function handleInputChange() {
const { files } = fileInput.current;
props.onChange(files[0]);
}
return (
<input
ref={setRef}
type="file"
placeholder={props.placeholder}
className="join-field-input"
onChange={handleInputChange}
/>
);
}
在Field
组件中使用它,表单状态将包含文件:
Use this within the Field
component, and the form state will contain the file:
<Field name="invitation[file]" placeholder="Upload csv file">
{({ input, meta, placeholder }) => (
// ...
<FileInput {...input} placeholder={placeholder} />
// ...
)}
</Field>
handleSubmitOnClick
还将获取整个values
对象.您的值应如下所示:
Also the handleSubmitOnClick
gets the whole values
object. Your values should look something like this:
values = { invitation: { file: {} } }
因此,将handleSubmitOnClick
函数更改为:
const handleSubmitOnClick = values => {
const data = new FormData();
const { file } = values.invitation;
data.append('file', file, file.name);
// ...
}
这是一个代码框.
这篇关于发出通过POST Axios& amp;将CSV文件提交到数据库的问题反应最终形式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!