-1

I am calling a javascript function to initialize a variable value in Oracle Visual Builder (VBCS). The function takes the binary data as input and needs to return Base64 converted string synchronously so that the Base64 converted string is assigned to the VBCS variable.

The function does not return the Base64 converted string. How do I make it return the Base64 string to the calling function?

PageModule.prototype.convertbase64 = function (data) {

    const blob = new Blob([data], {

      type: "application/octet-stream"

    });

    function blobToBase64(blob) {
      return new Promise((resolve, reject) => {
        const reader = new FileReader();
        reader.readAsDataURL(blob);
        reader.onloadend = () => resolve(reader.result.toString().substr(reader.result.toString().indexOf(',') + 1));
        reader.onerror = error => reject(error);
        console.log(new Date());
      });
    };

    const retstring = blobToBase64(blob).then(finalString => { return finalString });
 
    console.log('retstring value', retstring);

    return retstring;

};
jps
  • 20,041
  • 15
  • 75
  • 79
Vinb
  • 11
  • 1
  • 4
  • 1. Your promise does not return anything, just logs `new Date()`; 2. You log `retstring` before promise has finished it's `then` part. Move `console.log('retstring value', retstring);` `reader.onloaded`. – Justinas Jan 13 '22 at 07:15
  • @Justinas - The promise is fulfilled with a string, isn't it? – T.J. Crowder Jan 13 '22 at 07:16
  • `.then(finalString => { return finalString })` is pointless, it just creates a new promise that waits for the promise to be fulfilled, then passes on the fulfillment value. See also: https://stackoverflow.com/questions/29516390/how-to-access-the-value-of-a-promise – T.J. Crowder Jan 13 '22 at 07:18
  • 2
    What is `data`? – Kaiido Jan 13 '22 at 08:39
  • Reading a blob can be a time-consuming (in computer terms) operation; for instance, it may involve reading a file from disk. It's hard to prove a negative, but I don't think there are **any** methods available to read a blob's contents synchronously, which is why that code (which is a slightly out of date) is using `FileReader`. If you look at the [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) interface, you'll see several methods for reading its contents (`text`, `arrayBuffer`, `stream`), all of which are **a**synchronous. There's ... – T.J. Crowder Jan 13 '22 at 08:42
  • ...[`FileReaderSync`](https://developer.mozilla.org/en-US/docs/Web/API/FileReaderSync) (thanks @Kaiido!), but it's only available in workers, not the main thread. But it looks like your starting point is `data`, not the blob, so as Kaiido asked: What's `data`? And why don't [any of the previous questions with answers](/search?q=%5Bjs%5D+convert+to+base64) apply? – T.J. Crowder Jan 13 '22 at 08:43

1 Answers1

-1

The problem is in this line

const retstring = blobToBase64(blob).then(finalString => { return finalString });

You should wait for the result of blobToBase64 and make function convertbase64 async.

const retstring = await blobToBase64(blob);

Here is full example.

PageModule.prototype.convertbase64 = async function (data) {

const blob = new Blob([data], {
  type: "application/octet-stream"
});

function blobToBase64(blob) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.readAsDataURL(blob);
    reader.onloadend = () => resolve(reader.result.toString().substr(reader.result.toString().indexOf(',') + 1));
    reader.onerror = error => reject(error);
    console.log(new Date());
  });
};

const retstring = await blobToBase64(blob);

console.log('retstring value', retstring);

return retstring;
};

duy le
  • 53
  • 7
  • From the question: *"...need to return base64 converted string **syncronously**..."* By definition, an `async` function is **not** synchronous. – T.J. Crowder Jan 13 '22 at 07:35