0

I am trying to send a file from my React client to my Flask server.

State that holds file

  const [fileToUpload, setFileToUpload] = useState(null)

form

          <React.Fragment>
            <p className='margin-top' style={pStyles}>Attach your file</p>
            <form onSubmit={handleFileUpload} encType='multipart/form-data'>
              <input
                multi='false'
                type='file'
                onChange={(e) => handleSetFileValues(e)}
              />
              {currentCheck === 'file-radio' ? (
                <button type='submit' className='btn-blue'>Upload</button>
              ) : (
                null
              )}
            </form>
          </React.Fragment>

handleSetFileValues

  const handleSetFileValues = (e) => {
    setFileToUpload(e.target.files[0])
    setFileUrlToUpload('')
  }

handleFileUpload

  const handleFileUpload = async (e) => {
    // if (fileTitle === '' || fileToUpload !== null) return;
    e.preventDefault()

    const formData = new FormData();
    formData.append("file", fileToUpload);

    const { data, success, errorMessage } = await addServiceFile(service.id, formData, fileTitle)
    if (success) {
      console.log('res', data)
    } else {
      console.log('ERROR', errorMessage)
    }
  }

Upon submision I recieve a 400 res from the server. Logging formData shows an empty object, and the file object in the req payload is an empty object as well. any advice here would be great.

addServiceFile

export async function addServiceFile(serviceId, fileToUpload, fileLabel) {
  try {
    const body = {
      file: fileToUpload,
      file_label: fileLabel
    };

    return await awsApiRequest({
      method: 'POST',
      path: `/service/${serviceId}/file-data`,
      params: {
        body: body,
      },
    });
  } catch (error) {
    return error;
  }

ADDITIONAL CODE

awsApiRequest

export const awsApiRequest = async ({
  apiName = API_NAME,
  method = 'GET',
  path = '',
  params,
}) => {
  let apiRequest;
  switch (method) {
    case 'POST':
      apiRequest = API.post(apiName, path, params);
      break;
    case 'PUT':
      apiRequest = API.put(apiName, path, params);
      break;
    case 'PATCH':
      apiRequest = API.patch(apiName, path, params);
      break;
    case 'DELETE':
      apiRequest = API.del(apiName, path, params);
      break;
    case 'HEAD':
      apiRequest = API.head(apiName, path, params);
      break;
    case 'GET':
    default:
      apiRequest = API.get(apiName, path, params);
      break;
  }

  try {
    const responseData = await apiRequest;
    return {
      success: true,
      data: responseData,
    };
  } catch (error) {
    return {
      success: false,
      ...getApiErrorData(_.get(error, 'response', {})),
    };
  }
};export const awsApiRequest = async ({
  apiName = API_NAME,
  method = 'GET',
  path = '',
  params,
}) => {
  let apiRequest;
  switch (method) {
    case 'POST':
      apiRequest = API.post(apiName, path, params);
      break;
    case 'PUT':
      apiRequest = API.put(apiName, path, params);
      break;
    case 'PATCH':
      apiRequest = API.patch(apiName, path, params);
      break;
    case 'DELETE':
      apiRequest = API.del(apiName, path, params);
      break;
    case 'HEAD':
      apiRequest = API.head(apiName, path, params);
      break;
    case 'GET':
    default:
      apiRequest = API.get(apiName, path, params);
      break;
  }

  try {
    const responseData = await apiRequest;
    return {
      success: true,
      data: responseData,
    };
  } catch (error) {
    return {
      success: false,
      ...getApiErrorData(_.get(error, 'response', {})),
    };
  }
};

Flask Server Code

@bp.route("/service/<int:service_id>/file-data", methods=["POST"])
def add_service_file_data(service_id):
    file = request.files['file']
    file_label = request.json['file_label']

    add_new_service_file_data(service_id, file, file_label)

    response.status_code = 201
    return f'Uploaded succesfully: {file.filename}'

add_new_service_file_data

def add_new_service_file_data(service_id, file, file_label):
    new_file_data = ServiceFile(service_id=service_id, file_data=file.read(), file_label=file_label)

    try:
        db_session.add(new_file_data)
        db.commit()

    except:
        db_session.rollback()
        message = "Error Occured"
Ben_Sven_Ten
  • 529
  • 3
  • 21
  • What is `awsApiRequest`? And why are you storing a FormData object in a `file` property? –  Mar 15 '22 at 21:00
  • @ChrisG I added all the additional client and server code – Ben_Sven_Ten Mar 15 '22 at 21:05
  • You posted awsApiRequest twice, but what we need to see is `API.post` –  Mar 15 '22 at 21:21
  • @ChrisG ```API``` is a hook coming from ```AWSAmplify``` https://docs.amplify.aws/lib/restapi/fetch/q/platform/js/ I dont think the problem lies anywhere there as I am getting a response from the server – Ben_Sven_Ten Mar 15 '22 at 22:48
  • As far as I can tell you're posting `{ body: { file: aFormDataObject }}` via (ultimately) axios. I don't think that's going to work. Did you inspect the POST request in the browser's dev tools? You should see a `multipart/form-data` request with a body containing boundaries and your file as binary –  Mar 15 '22 at 22:55
  • @ChrisG in the payload the file object is in fact empty – Ben_Sven_Ten Mar 15 '22 at 23:15
  • Here's how to upload a file with axios, maybe this will help: https://stackoverflow.com/questions/43013858/how-to-post-a-file-from-a-form-with-axios/43014086#43014086 (bottom line: you need to set the encoding and pass the FormData object directly) –  Mar 15 '22 at 23:17

0 Answers0