Custom component to upload a file from retool

I created the below custom component to upload files from retool to the backend,
When I select a file, and then try to inspect the component value, I am not getting anything

{{ customComponent1.model.file }} -> {}

Model:

{ file: {} }
<style>
  body {
    margin: 0;
  }
</style>
<script
  src="https://cdn.tryretool.com/js/react.production.min.js"
  crossorigin
></script>
<script
  src="https://cdn.tryretool.com/js/react-dom.production.min.js"
  crossorigin
></script>
<script src="https://unpkg.com/@material-ui/core@3.9.3/umd/material-ui.production.min.js"></script>

<div id="react"></div>

<script type="text/babel">
  const MyCustomComponent = ({ triggerQuery, model, modelUpdate }) => {
    return (
      <input
        id="upload"
        type="file"
        onChange={(event) => {
          console.log(event.target.files[0]); modelUpdate({ file: event.target.files[0] });
        }}
      />
    );
  };

  const ConnectedComponent = Retool.connectReactComponent(MyCustomComponent);
  ReactDOM.render(<ConnectedComponent />, document.getElementById("react"));
</script>

I dont want to use the already existed component, as i am getting base64 string

Hi @Karan

You'll end up to transform the file source as string in any case because you cannot pass a native object (the File object) betweet the iframe of the custom component to Retool.

I guess you can convert the base64 to binary in js, such this solution:

Hope this help.

I did the workaround you mentioned. But the variable is still the same, getting a null value. Not getting the binary, but when I console.log in the function, was able to see the Blob content

const sliceSize = 512;
const byteCharacters = atob(fileInput1?.value[0]);
const byteArrays = [];

for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
  const slice = byteCharacters.slice(offset, offset + sliceSize);

  const byteNumbers = new Array(slice.length);
  for (let i = 0; i < slice.length; i++) {
    byteNumbers[i] = slice.charCodeAt(i);
  }

  const byteArray = new Uint8Array(byteNumbers);
  byteArrays.push(byteArray);
}

const blob = new Blob(byteArrays, { type: fileInput1?.files?.[0]?.type });

// var pdf_url = URL.createObjectURL(blob);

// console.log(pdf_url, {
//   r: URL.revokeObjectURL(pdf_url)
// });


return blob --> Null value;