FaFa
FaFa

Reputation: 398

How to push a file in a base64 format in array?

I am trying to push to the data array the object with the file and file base64 format in getBase64. But when I console log data array it is empty, also I can turn file into base64 format. But I don't understand why the push method in getBase64 doesn't work. How do I get bot the file and file base 64. enter image description here

export default function UploadDoc({ setInputs }) {
  function beforeUpload(file) {
    const isRightType =
      file?.type === "application/pdf" ||
      file?.type === "application/xlsx" ||
      file?.type === "image/jpeg" ||
      file?.type === "application/csv" ||
      file?.type === "text/plain";
    if (!isRightType) {
      message.error("You can only upload PDF, TXT, JPEG, CSV or XLSX  files!");
    }
    const isLt2M = file?.size / 1024 / 1024 < 2;
    if (!isLt2M) {
      message.error("PDF must be smaller than 2MB!");
    }
    setFileList((state) => (state ? [...state, file] : [file]));
    return isRightType && isLt2M;
  }

  const overrideRequest = ({ file, onSuccess, onError }) => {
    // <Upload/> renders another component (rc-upload) as its child which handles the actual AJAX upload.
    // You can override this behaviour by passing a customRequest prop to <Upload/>
    const isRightType =
      file?.type === "application/pdf" ||
      file?.type === "image/jpeg" ||
      file?.type === "application/csv" ||
      file?.type === "text/plain";
    if (isRightType) {
      setTimeout(() => {
        onSuccess("ok");
      }, 1);
    } else {
      setTimeout(() => {
        onError("ok");
      }, 1);
    }
  };

 const getBase64 = (file) =>
    new Promise((resolve) => {
      // turns file data in loggable and readable data from javascript
      const reader = new FileReader();
      reader.onloadend = () => resolve(reader.result);
      reader.readAsDataURL(file);
    });

  const dispatch = useDispatch();
  const fileList = useSelector((state) => state.filesFileListReducer);

  const handleUploadChange = (info) => {
    if (info.file.status === "error") {
      console.log("error", info.file);
    }

   if (info.file.status === "done") {
      // Get this url/data from response in real world.

      const arr = [];

      info.fileList.forEach(async (file) => {
        const fileInfo = await getBase64(file.originFileObj);
        const infoOnUploadedFile = { base64: fileInfo, fileObj: file };
        console.log("file info", infoOnUploadedFile);
        arr.push(infoOnUploadedFile);
      });
      console.log("data", arr);
      
    }
  };

  return (
    <Upload
      {...{
        multiple: true,
        beforeUpload: (file) => beforeUpload(file),
        accept: ".txt, .csv, .jpeg, .pdf",
        customRequest: (info) => overrideRequest(info),
        onChange: (info) => handleUploadChange(info),
        onRemove: (file) => {
          const newFileList = fileList?.filter(
            (fileGrp) => fileGrp.fileObj !== file
          );
          dispatch(setFileList(newFileList));
          setInputs((state) => ({
            ...state,
            docs: newFileList && newFileList.map((file) => file?.fileBase64),
          }));
        },
      }}
    >
      <Button icon={<UploadOutlined />} style={{ width: "100px" }} />
    </Upload>
  );
}

Upvotes: 0

Views: 958

Answers (1)

Elikill58
Elikill58

Reputation: 4908

You are trying to get an object before his availability.

Such as you want to get the value but directly, You can use async/await feature (wiki).

For you, something like this will fix it :

const getBase64 = (blob: Blob) => {
  return new Promise((resolve) => {
    const reader = new FileReader()
    reader.onloadend = () => resolve(reader.result)
    reader.readAsDataURL(blob) // read blob
  })
}

const obj = await getBase64(resBlob); // wait until method not finished
// now you can check if obj is defined and push it into array

Upvotes: 1

Related Questions