Base64 decoding and file upload to API (Pocketbase) doesn't work

Hi everybody

I'm currently building a small internal tool. For the backend, I'm using Pocktebase which I integrated through the API. Pocketbase also has a file system that I want to use for uploaded files. Unfortunately, Pocketbase doesn't accept Base64 encoded files and I need to decode them first.

I already tried a ton of different ways described here in the forum to decode it, but never get a value back when using a transform or JS query (see code below).

Also, already looked into this Custom component to upload a file from retool - #2 by abusedmedia but that also didn't do the job...

Does somebody maybe have an easy way to decode files?
Besides that, why is Retool even encoding files as base64?

JS query with patch request (can also provide you other attempts if needed):

const customerId = postCustomer.data.id; 

// b64toBlob function
function b64toBlob(b64Data, contentType = "", sliceSize = 512) {
  const byteCharacters = atob(b64Data);
  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: contentType });
  return blob;
}

if ({{fileLogoColor.length}} === 0) {
  throw new Error('No file selected');
}

const base64String = fileLogoColor.value[0];
const contentType = fileLogoColor.files[0].type;

const decodedFile = b64toBlob(base64String, contentType);

const formData = new FormData();
formData.append('logo_color', decodedFile, 'decodedFile');

const response = await fetch(`http://api-example.com/api/collections/customer/records/customerId`, {
  method: 'PATCH',
  body: formData,
});

if (!response.ok) {
  throw new Error('Failed to update the record');
}

const updatedRecord = await response.json();
return updatedRecord;

Hey @joel-blynx! Based on the code you provided, it seems like you may not be passing the customerId variable to the URL correctly. Instead of using customerId directly in the URL string, you can concatenate it like this:

const response = await fetch(`http://api-example.com/api/collections/customer/records/{customerId}`, { method: 'PATCH', body: formData, });

or maybe like this:

const response = await fetch("http://api-example.com/api/collections/customer/records/" + customerId, { method: 'PATCH', body: formData, });

Regarding your question on why Retool is encoding files as Base64, one of the reasons I can imagine is because some APIs expect binary data to be encoded as text in a specific format such as Base64. Therefore, Retool encodes files as Base64 to support these APIs.

To step back a bit, how are the files getting into Retool?

\