Загрузка изображений в React путем слияния объекта и файла DataForm - PullRequest
0 голосов
/ 19 февраля 2020



Я изо всех сил пытался найти решение, чтобы загрузить изображение и сохранить его в базе данных.
Опробовал их все: Dropzone, Reaction-Dropzone, Reaction-Uploader и т. Д. c .....

API BackEnd ожидает этого:

{
  "course": {
    "title": "Hic et velit sed.",
    "subtitle": "Omnis quibusdam illum itaque.",
    "description": "Et ullam ipsum. Illum dolor odit. Id veritatis ducimus.",
    "end_date": "2020-02-01",
    "attachment_attributes": {
      "file": {
        --- here the uploaded data file ---
      }
    }
  }
}

Мой компонент теперь записывается только с 1 типом ввода = файл, чтобы ускорить это тестирование , Требования API, такие как title, subtitle et c., Будут жестко закодированы.

Здесь компонент:

import React, { Component } from 'react';
import api from '../../../../helpers/API';

class Uploader extends Component {
  constructor(props) {
    super(props);
      this.state = {
        selectedFile: null
      }
  }
  onChangeHandler = event => {
    this.setState({
      selectedFile: event.target.files[0],
      loaded: 0,
    })
  }

  onClickHandler = () => {

   ** HARDCODED API REQUIREMENT**    
   const body = "course": {
      "title": "Hic et velit sed.",
      "subtitle": "Omnis quibusdam illum itaque.",
      "description": "Et ullam ipsum. Illum dolor odit. Id veritatis ducimus.",
      "end_date": "2020-02-01",
      "attachment_attributes": {
        "file": {
          --- here the uploaded file data ---
        }
      }
    }    

   ** THIS SHOULD HANDLE THE UPLOADED FILE DATA FORMAT **    
    const data = new FormData()
    data.append('file', this.state.selectedFile)

    return api
      .post("http://localhost:3000/api/v1/files", ??????). <— DATA or BODY?
      .then(res => { 
        console.log(res.statusText)
      })
      .catch(res => console.log('error ==> ', res))
  }

  render() {
    return (
      <>
        <div>
          <label>Upload Your File </label>
          <input 
            type="file"
            multiple onChange={this.onChangeHandler}/>
        </div>   
        <button type="button" className="btn btn-success btn-block" onClick={this.onClickHandler}>Upload</button>
      </>
    )
  }
}

export default Uploader

Issue

Если я передаю DATA в вызове API, загруженный файл хорошо сохраняется в разделе Browser > Network > Header > Data Form в виде файла: двоичный файл

И это хорошо.

Но мне нужно передать загруженный файл как часть моего объекта BODY. Итак, ниже то, что я сделал, но возвращается пустым:

onClickHandler = () => {
    const data = new FormData()
    data.append('file', this.state.selectedFile)

    const body = {
      "course": {
        "title": "Hic et velit sed.",
        "subtitle": "Omnis quibusdam illum itaque.",
        "description": "Et ullam ipsum. Illum dolor odit. Id veritatis ducimus.",
        "end_date": "2020-02-01",
        "attachment_attributes": {
          "file": data  <-- trying to pass the uploaded DataForm here
        }
      }
    }

    return api
      .post("http://localhost:3000/api/v1/files", body)
      .then(res => { 
        console.log(res.statusText)
      })
      .catch(res => console.log('error ==> ', res))
  }

К сожалению, я получаю 422 error, {"errors":{"attachment.file":["blank"]}}

Любая помощь очень ценится. Спасибо
Джоу

1 Ответ

0 голосов
/ 19 февраля 2020

ОК, нашел способ.

Невозможно вызвать DataForm загруженного файла из ОРГАНА ОБЪЕКТА.

Что нужно сделать, это data.append каждого отдельного элемента в объекте.

Здесь файл:

const data = new FormData()
data.append('course[title]', "Hic et dddvelit sed.")
data.append('course[subtitle]', "Omnis quibusdam illum itaque.")
data.append('course[description]', "Et ullam ipsum. Illum dolor odit. Id veritatis ducimus.")
data.append('course[end_date]', "2020-02-01")
data.append('course[attachment_attributes][file]', this.state.selectedFile)

Таким образом, Browser > Network > Header > Data Form, покажет каждый элемент, переданный правильно, и загруженное изображение будет поддерживать двоичный формат.

Вот предварительный просмотр:

course[title]: 6666Hic et dddvelit sed.
course[subtitle]: Omnis quibusdam illum itaque.
course[description]: Et ullam ipsum. Illum dolor odit. Id veritatis ducimus.
course[end_date]: 2020-02-01
course[attachment_attributes][file]: (binary)

POST API будет выглядеть следующим образом:

return api
  .post("http://localhost:3000/api/v1/courses", data)
  .then(res => { 
    console.log(res.statusText)
  })
  .catch(res => console.log('error ==> ', res))

Я действительно надеюсь, что это может помочь кому-то еще, потому что он имеет сводил меня с ума в течение нескольких недель.

Удачного кодирования. Джо

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...