Upload multiple documents react JS

Viewed 58

So I have to upload a list of Documents, I have in my code two services, one to get the document type and setup the frontend, and the other to upload the documents.

const getDocumentType = async () => {
    const path = "endpoint";
    const request = {
        method: "GET",
        headers: {
            "Content-type": "application/json",
        }
    }
    try {
        const result = await fetch(path, request);
        let response = await result.json();
        return response;
    } catch (error) {
        return error
    }

}

const postLoadDocument = (data) => {
    const dataBody = {
        documentType: data.documentType,
        refundId: data.refundId,
        index: data.index,
        file: data.file,
        fileName: data.fileName,
    }
    const path = "endpoint"
    const request = {
        method: "POST",
        headers: {
            "Content-Type": "application/json",
        },
        body: JSON.stringify(dataBody)
    };
    try {
        const result = await fetch(path, request);
        let response = await result.json();
        return response;
    } catch (error) {
        return error
    }
}

export { getDocumentType, postLoadDocument }

also I have an Input component to map through what getDocumentType brings: Input component


var fileName;

const Input = ({ setValue, setFileName, id }) => {
    const handleInput = (e) => {
        const value = e.target.value;
        if (value !== null) {
            if (e.target.files[0].size < 5000000) {
                fileName = e.target.files[0].name;
                setFileName(fileName);
                const reader = new FileReader();
                reader.readAsDataURL(e.target.files[0]);
                reader.onloadend = () => {
                    setValue(reader.result);
                }
            }
        }
    }
    return (
        <div>
            <form>
                <label>
                    load your file
                </label>
                <input
                    type="file"
                    accept=".png, .jpg, .pdf"
                    onChange={(e) => handleInput(e)}
                />
            </form>
        </div>
    )
}

export default Input;

and the main component that wraps everything looks like this:

import Input from "./components/input.js";
import { getDocumentType, postLoadDocument } from "./service/documentLoad.js"

function App() {
  const [fileLoad, setFileLoad] = useState(null);
  const [fileName, setFileName] = useState("");
  const [documentsType, setDocumentType] = useState([]);

  useEffect(() => {
    getDocumentType().then((obj) => {
      setDocumentType(obj.result)
    })
  }, [])

  const saveData = () => {
    const data = {
      // data ...
      file: fileLoad,
      fileName: fileName,
    }
      (async () => {
        const response = await postLoadDocument(data);
        return response;
      })();
  }

  return (
    <div className="App">
      {documentsType !== undefined &&
        documentsType.length !== 0 &&
        documentsType.map((documentType, index) => (
          <div>
            <span>{documentType.name}</span>
            <span>{documentType.description}</span>
            <Input id={index} setValue={setFileLoad} setFileName={setFileName} />
          </div>
        ))}

      <button onClick={saveData}>Load documents</button>
    </div>
  );
}

export default App;

so the problem comes when I try to upload the documents...it looks like the inputs overlap one each other and only sends the last document choos. How to identify every input from the other and upload the document list?

1 Answers

There are two problems I see here. First, you want to add the attribute "multiple" to your input. This will allow your input to accept multiple files. Basically, just after the line "onChange={(e) => handleInput(e)}" add a new line with only the word "multiple".

Second problem is that inside of your handleInput function you always use the first element of the files list. Instead, what you should do, is iterate through all of the files in the "files" list. As you iterate through the files you should handle each file.

For example, here is a JavaScript version of handleInput that just logs out each file object to the console. This version of handleInput expects that FileList object (what you get from event.target.files) will be given as the only argument.

function handleInput(fileList){
    for(let index = 0; index < fileList.length; index ++){
        let file = fileList[index];
        console.log(file);
    }
}

Related