[Solved] Image icon/tag showing although dataset field is empty

Hello!
I am using a repeater to display images on dynamic item pages. The number of images per item vary between 1 and 3, and consequently, if the image2 and/or image3 field is empty I want there to be nothing showing on the page. However, now I get this:


The little ‘broken image’ icon and image1 tag still showing really annoys me!
I’ve scoured the forum for similar issues and attempted this string of code in order to conditionally hide/show the repeater items:

$w("#repeater1").onItemReady( ($w, itemData, index) => {
    console.log(itemData.image2);    
 if(itemData.image2 === "null") {
        $w("#image25").hide();
    }
 else {     
        $w("#image25").show();
    }
});

Can’t get it to work. Any help appreciated!
Thanks!

Hi Helena

Any reason you’re using a repeater instead of a gallery…? I’ve got a nice bit of code here that is basically plug and play for a gallery that you can probably adapt to populate the repeater correctly…, see below:

$w.onReady(function () {
 $w('#dynamicDataset').onReady(() => {
 let item = $w('#dynamicDataset').getCurrentItem();
 let itemsForGallery = [];
 for (let i = 1; i < 4; i++) {
 if (item[`image${i}`]) {
    itemsForGallery.push({src: item[`image${i}`] });
    }
 }
    $w("#gallery1").items = itemsForGallery;
   });
});

Hi Helena:

I think Tiaan’s proposal is a good one.

In case you are also interested in understanding why your code isn’t working here is some feedback:

$w("#repeater1").onItemReady( ($w, itemData, index) => { 
    console.log(itemData.image2);
    if(itemData.image2 === "null") { 
        $w("#image25").hide(); 
   } else {
       $w("#image25").show();
   }
 });

the value null is not a string it is an actual javascript primitive value representing the absence of a value.
Check out this link: null - JavaScript | MDN

The simple way to test for null is to use the not operator - !. The other way is to reverse the logic so instead of testing for the absence of a value, test for its existence. I would also make sure that the image2 name has a length > some expected minimal value (at a minimum > 0 ). So you could change your code to be as follows

$w("#repeater1").onItemReady( ($w, itemData, index) => {
      console.log(itemData.image2);
      // Note I have reversed the logic to make the code easier to read
      if(itemData.image2 && itemData.image2.length > 0) {
          $w("#image25").show();
     } else { 
          $w("#image25").hide();
     }
});

Hope this is helpful.

Thank you both!

Tiaan,
I chose a repeater since I couldn’t figure out a way to link a gallery to multiple database fields (image1, image2, image3)… I know next to nothing about Javascript, as you can tell :slight_smile: I just attempted to use your suggested code on a gallery, and it does indeed adjust to the number of images available for the current database item, but is not able to retrieve any pictures. Just shows grey boxes and a ‘processing’ symbol.

strcroppe,
Your code works really well on the repeater, although the icons appear for a second while waiting for the repeater to populate (because of ‘onItemReady’, right - can’t change that to ‘onPageReady’, can you?). I didn’t know ‘length’ existed or was applicable to names - thought you needed to use some kind of boolean value. Makes sense!

Hi Helena

To really help you out you need to either share the whole page code or point us at the web site so we can look at the code in a debugger. At this point all you will get is speculation sadly.

Cheers

Hi Helena

That sounds like a datavase permissions issue to me, best guess… I run that code on multiple sites and it’s always worked like charm.

Share your page code so we can take a look.

Thanks
Tiaan

Tiaan, yes could be. Nothing like seeing the code in situ :wink:

Thank you.
An example of affected pages is this one: https://www.borders-territories.space/Projects/Research/71.
Code for this dynamic item page is currently (following stcroppe’s example):

$w("#repeater1").onItemReady( ($w, itemData, index) => {
      console.log(itemData.image2);
 if(itemData.image2 && itemData.image2.length > 0) {
          $w("#image25").show();
     } else { 
          $w("#image25").hide();
     }
});

$w("#repeater1").onItemReady( ($w, itemData, index) => {
      console.log(itemData.image3);
 if(itemData.image3 && itemData.image3.length > 0) {
          $w("#image24").show();
     } else { 
          $w("#image24").hide();
     }
});


Hi Helena:

OK This is the error being reported by the browser:


What this is saying is that it doesn’t know what to do with this code on line 1.

$w("#repeater1").onItemReady( ($w, itemData, index) => {

There is also another problem and that is that you only need one of these blocks not two. So you need to consolidate the two onItemReady functions into one.

The way to make sure that the selector is usable is to use it either in a function or, in this case, the page onReady function like so.

$w.onReady(() => {
    $w("#repeater1").onItemReady( ($w, itemData, index) => {
        console.log(itemData.image2);
        if(itemData.image2 && itemData.image2.length > 0) {
           $w("#image25").show();
        } else { 
           $w("#image25").hide();
        }
        console.log(itemData.image3);
        if(itemData.image3 && itemData.image3.length > 0) {
            $w("#image24").show();
        } else { 
            $w("#image24").hide();
        }
    });

    $w("#dynamicDataset").onReady( ($w, itemData, index) => {
        console.log(itemData.document);
        if(itemData.document.length > 0) {
            $w("#button4").show();
        } else { 
            $w("#button4").hide();
        }
    });
});

Try this and see if it works.

Cheers
Steve

One last thought there is another error that is being generated because you are probably binding the itemData.image field to the $w(‘#image’) using the icon in the editor. What you might want to consider is doing the binding in this code block also using $w(‘#image24’).src.

So unbind the editor mapping and change your code to look like this:

$w.onReady(() => {
    $w("#repeater1").onItemReady( ($w, itemData, index) => {
        console.log(itemData.image2);
        if(itemData.image2 && itemData.image2.length > 0) {
            // We have an image assign it to the element for display
            $w("#image25").src = itemData.image2;
            $w("#image25").show();
        } else {
            $w("#image25").src = ''; // No Image - do not use null
            $w("#image25").hide();
        }
        console.log(itemData.image3);
        if(itemData.image3 && itemData.image3.length > 0) {
            // We have an image assign it to the element for display
            $w("#image24").src = itemData.image3;
            $w("#image24").show();
        } else {
            $w("#image25").src = ''; // No Image - do not use null
            $w("#image24").hide();
        }
     });
     $w("#dynamicDataset").onReady( ($w, itemData, index) => {
         console.log(itemData.document);
         if(itemData.document.length > 0) {
             $w("#button4").show();
         } else {
             $w("#button4").hide();
         }
     });
  });

stcroppe,
the last code works perfectly for the repeater, thank you so much for taking the time!
However ‘button4’ is still showing regardless of ‘document’ field being empty or not. I tried both the above suggested code and this (same syntax throughout):

$w.onReady(() => {
    $w("#repeater1").onItemReady( ($w, itemData, index) => {
        console.log(itemData.image2);
 if(itemData.image2 && itemData.image2.length > 0) {
 // We have an image assign it to the element for display
            $w("#image25").src = itemData.image2;
            $w("#image25").show();
        } else {
            $w("#image25").src = ''; // No Image - do not use null
            $w("#image25").hide();
        }
        console.log(itemData.image3);
 if(itemData.image3 && itemData.image3.length > 0) {
 // We have an image assign it to the element for display
            $w("#image24").src = itemData.image3;
            $w("#image24").show();
        } else {
            $w("#image24").src = ''; // No Image - do not use null
            $w("#image24").hide();
        }
     });
     $w("#dynamicDataset").onReady( ($w, itemData, index) => {
         console.log(itemData.document);
 if(itemData.document && itemData.document.length > 0) {
          $w("#button4").src = itemData.document;
            $w("#button4").show();
        } else {
            $w("#button4").src = ''; 
            $w("#button4").hide();
         }
     });
  });

Is it because the field is called ‘Document’ that I get issues? Or because I’m using the code written for a repeater on the dynamic dataset as a whole?

Hi Helena

Your page is flagging that itemData is undefined and so an error and the reason why is that the dataset onReady function doesn’t deliver any arguments to the handler function.


Sorry I should have picked this up earlier. You have to get the item data using the getCurrentItem() function.

So replace this code:

$w("#dynamicDataset").onReady( ($w, itemData, index) => {
    console.log(itemData.document);

with

$w("#dynamicDataset").onReady(() => {
    let itemData = $w('#dynamicDataset').getCurrentItem();
    console.log("Dumping current itemData");
    console.log(itemData);

This should get you to (or closer to) a solution :wink:

Hi again!
Now everything works the way I want it to! Thank you so much.
If someone else is interested, my final code as follows:

$w.onReady(() => {
    $w("#repeater1").onItemReady( ($w, itemData, index) => {
        console.log(itemData.image2);
 if(itemData.image2 && itemData.image2.length > 0) {
            $w("#image25").src = itemData.image2;
            $w("#image25").show();
        } else {
            $w("#image25").src = ''; 
            $w("#image25").hide();
        }
        console.log(itemData.image3);
 if(itemData.image3 && itemData.image3.length > 0) {
            $w("#image24").src = itemData.image3;
            $w("#image24").show();
        } else {
            $w("#image24").src = ''; 
            $w("#image24").hide();
        }
     });
    $w("#dynamicDataset").onReady(() => {
 let itemData = $w('#dynamicDataset').getCurrentItem();
    console.log("Dumping current itemData");
    console.log(itemData);
 if(itemData.document && itemData.document.length > 0) {
            $w("#button4").show();
        } else {
            $w("#button4").hide();
         }
     });
  });
2 Likes

Hi Helena

Very cool! I hope you manage to get your Project/Team challenge sorted out as well.

Steve

Steve,
Diving into that as soon as I’m able to set field to Multiple items… You always get stuck on the small stuff! Thanks again.

OK well if you need any more pointers feel free to drop me an email. See my profile.

hello
please can anyone help me?

$w.onReady(() => {
//TODO: write your page related code here…
$w(“#repeater1”).onItemReady( ($w, itemData, index) => {
console.log(itemData.postImage);
if (itemData.postImage && itemData.postImage.length > 0) {
$w(“#image5”).show();
} else {
$w(“#image5”).collapse();
}

i tried implementing the code but it is not working.
this is the error it shows.

please help me out. i have been trying for three days now. i am starting to feel no hope