Set image source from datasource base64 string

Is it possible to hook a List from datasource with flListDataAfterGetData and set an image source to a base64 image string?

I have the following but this is my first time reading the data in javascript and I’m unsure how to reference the column (Picture) or set the image display field source with the base64 encoded text transformed to a jpg:
Fliplet.Hooks.on(‘flListDataAfterGetData’, function (options) {
.forEach(options.records, function(record) {
//Fliplet.Dencode.base64()
});

});

I don’t believe Fliplet has a decode for base64, so I’ve used this:
var b64String = record.data[‘Picture’];
//alert(b64String);
var decodedString = atob(b64String);

I do not know how to now set the Picture field from the datasource to the decoded string and then set the source of the list from datasource image field to this data.

Update: Getting closer, but alerts do not show the b64 data and the images are still not displaying. Any help would be appreciated.

Fliplet.Hooks.on(‘flListDataBeforeRenderList’, function(data) {

// The data.records contains the entries fetched by the component
var entries = data.records;

var count = 0;
var insideCount = 0;

// Process each entry to decode Base64 and update the image column
entries.forEach(function(entry) {
if(entry.data[‘Picture’].trim() !== “Not Found”){

  if(count < 1){
   	alert("Count: " + count);
    count++;
  }
  
  if (typeof entry.data['Picture'] === 'string') {
    
			var base64regex = /^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/;
    
   // alert(bPic);
    try {
      // Check if the string is a valid Base64 or already a data URI
      var bPic = /^data:image\/[a-z]+;base64,/.test(entry.data['Picture']);
      //var bPic2 = /^[A-Za-z0-9+/=]+$/.test(entry.data['Picture']);
      var bPic3 = base64regex.test(entry.data['Picture']);
      if (bPic) {
        alert("Already a data URI, no decoding needed");
        
        // Already a data URI, no decoding needed
        return;
      } else if (bPic3) {
        // Assuming it's raw Base64, create a data URI
        var dataUri = 'data:image/jpeg;base64,' + entry.data['Picture']; // Adjust mime type if needed
        
       // alert("dataUri: " + dataUri);
        
        entry.data['Picture'] = dataUri; // Replace the column value
        
        if(insideCount < 1){
         	alert("Entry:" + entry.data['Picture']);
          insideCount++;
        }
      }
      else{
         //alert("bPic: " + bPic);
        //alert("bPic2: " + bPic2);
      }
    } catch (e) {
      console.error('Error processing Base64 for entry:', entry.id, e);
      alert("Error");
      // Set a fallback 1x1 transparent pixel image
      entry.data['Picture'] = 'data:image/jpeg;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAACklEQVR4nGMAAQAABQABDQottAAAAABJRU5ErkJggg==';
    }
  }
}else{
  if(count < 1){
   	alert("Entry:" + entry.data['Login ID'] + "||");
    count++;
  }
}

});
});

Hi Micheal,

Just so I understand the situation, you have a a list of entries in the data source and the Picture column contains base64 strings? You want to display these are images in the LFD, is that correct?

Thanks,
Deb

Yes. 100%

This is the error I’m getting:
Uncaught (in promise) TypeError: Cannot read properties of undefined (reading ‘Picture’)
at preview?disableSecurity&disableNavigation&auth_token=us–session–c6dea04ff65cef5a0a2c1ad16084c8cd-607-479-0009:599:18
at Array.forEach ()
at preview?disableSecurity&disableNavigation&auth_token=us–session–c6dea04ff65cef5a0a2c1ad16084c8cd-607-479-0009:598:11
at fliplet-core.bundle.js?=35b39f:1466:29
at Array.map ()
at Object.run (fliplet-core.bundle.js?
=35b39f:1465:54)
at DynamicList.renderLoopHTML (small-h-card-code.js?=1741095380:650:24)
at small-h-card-code.js?
=1741095380:501:13

Hi Michael, you can use this code.

function setBase64Image(base64String, imgElementId) {
  let imgSrc = base64String.trim(); // Remove extra spaces
  
  // Check if the string already includes a data URI
  if (!imgSrc.startsWith("data:image")) {
    // Try to detect MIME type from the Base64 string (optional, but helpful)
    let mimeType = "image/png"; // Default MIME type
    if (imgSrc.charAt(0) === "/") mimeType = "image/jpeg";
    else if (imgSrc.charAt(0) === "R") mimeType = "image/gif";
    else if (imgSrc.charAt(0) === "i") mimeType = "image/png";
    else if (imgSrc.charAt(0) === "U") mimeType = "image/webp";
    
    // Add the proper data URI prefix
    imgSrc = `data:${mimeType};base64,${imgSrc}`;
  }

  return imgSrc
}

Fliplet.Hooks.on('flListDataAfterGetData', function(options) {
  options.records = options.records.map(el => {
    el.data.Picture = el.data.Picture ? setBase64Image(el.data.Picture) : ""
    return el
  })
});

Hope this will solve your problem.

Kind regards,
Veljko

1 Like

Thank you very much for this. It does work, however it’s very slow. Can it be called asynchronously?

Hi Micheal,

That depends on what part is slow, I am guessing loading large base 64 strings for many records will be slow due to the amount of data that is downloaded. You best option there is to set a limit to the LFD or apply some sort of filter to reduce the number of records being loaded. Obviously there is the option of uploading the images to our file system and putting the links for the files against each record which would significantly reduce the amount of data being downloaded.

Thanks,
Deb

1 Like