发出通过POST Axios& amp;将CSV文件提交到数据库的问题反应最终形式 [英] Issue to submit CSV file to DB via POST Axios & React-Final-Form

查看:138
本文介绍了发出通过POST Axios& amp;将CSV文件提交到数据库的问题反应最终形式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要使用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,并且向数据库的提交工作正常. 问题是当我尝试将CS​​V的内容传递给将处理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; amp;将CSV文件提交到数据库的问题反应最终形式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆