Concatenate data from CMS to a repeater in dynamic item page

I am trying to concatenate data from a CMS to then display it in the text field of a repeater of a dynamic item page.

The datas are correctly loaded and concatenated, but only certain repeater items are correctly updated, the others keep the default text of the design.

Could you please help me, as I’ve been stuck on this for several days?

:white_circle: The part of code that does not work properly :

$w('#repeaterAwards').forEachItem(($item, data) => {
    if (data._id === item._id) {
        $item('#award').text = concatenatedData;
        //console.log("\n",data,"\n",concatenatedData,"\n");
    }
});

:white_circle: Full page code :

import wixData from 'wix-data';

// Utility function to show, expand, and mute/unmute a video
function showAndExpand(elementToShow, elementToHide, videoToPlay) {
    elementToShow.expand();
    videoToPlay.mute();
    elementToHide.collapse();
}

$w.onReady(function () {
    // Necessary initializations
    $w('#boxAward').hide();
    $w('#dataset2').onReady(() => {
        // Handling the alternating display of videos
        $w('#repeaterCompetences').onItemReady(($repeaterItem, repeaterItemData) => {
            let even = repeaterItemData.order;
            let videoPlayer = even % 2 === 0 ? $repeaterItem('#videoPlayer2') : $repeaterItem('#videoPlayer1');

            // Start the video when the corresponding part is visible in the viewport
            $repeaterItem('#v1').onViewportEnter(() => {
                videoPlayer.play();
            });

            $repeaterItem('#v2').onViewportEnter(() => {
                videoPlayer.play();
            });

            // Display and configure videos alternately
            if (even % 2 === 0) {
                showAndExpand($repeaterItem('#v2'), $repeaterItem('#v1'), $repeaterItem('#videoPlayer2'));
            } else {
                showAndExpand($repeaterItem('#v1'), $repeaterItem('#v2'), $repeaterItem('#videoPlayer1'));
            }
        });

        // Loading data from the "Awards" collection
        wixData.query("Awards")
            .find()
            .then(res => {

                // After loading data, trigger the synchronized fade
                let areImagesHidden = true;
                const intervalBetweenImagesInMs = 500;
                const fadeDurationInMs = 500;

                $w('#repeaterAwards').onItemReady(($item, itemData, index) => {
                    $item('#boxAward').hide();

                    // Processing collection items
                    res.items.forEach(item => {
                        // Constructing the concatenated string with line breaks
                        let concatenatedData = `${item.award}\n${item.festival}`;
                        if (item.city) concatenatedData += `\n${item.city}`;
                        if (item.year) concatenatedData += ` ${item.year}`;

                        // Updating text in the repeater
                        $w('#repeaterAwards').forEachItem(($item, data) => {
                            if (data._id === item._id) {
                                $item('#award').text = concatenatedData;
                                //console.log("\n",data,"\n",concatenatedData,"\n");
                            }
                        });
                    });

                    // Start synchronized fade when the repeater is visible in the viewport
                    $w('#repeaterAwards').onViewportEnter(() => {
                        if (areImagesHidden) {
                            $w('#repeaterAwards').forEachItem(($item, itemData, index) => {
                                setTimeout(() => {
                                    $item('#boxAward').show('flip', { duration: fadeDurationInMs });
                                    $item('#boxAward').show('fade', { duration: fadeDurationInMs });
                                }, intervalBetweenImagesInMs * index);
                            });
                            areImagesHidden = false;
                        }
                    });
                });
            })
            .catch(err => {
                console.error(err);
            });
    });

    // Handling page scrolling
    $w('#piedPage').onViewportEnter(() => {
        $w('#scrollDownIndicator').hide('fade', { duration: 300 });
    });

    $w('#piedPage').onViewportLeave(() => {
        $w('#scrollDownIndicator').show('fade', { duration: 300 });
    });
});

Hello,

I would need to test your code but why not just set the repeater data like you are already doing, then populate the repeater from your data query? You are manipulating your returned data by doing a “forEachItem” call but you are not setting that data to the repeater afterwards. I would’ve done this logic differently but you can try and plug this into your function like below:

YOUR CODE
// Processing collection items
                    res.items.forEach(item => {
                        // Constructing the concatenated string with line breaks
                        let concatenatedData = `${item.award}\n${item.festival}`;
                        if (item.city) concatenatedData += `\n${item.city}`;
                        if (item.year) concatenatedData += ` ${item.year}`;

                        // Updating text in the repeater
                        $w('#repeaterAwards').forEachItem(($item, data) => {
                            if (data._id === item._id) {
                                $item('#award').text = concatenatedData;
                                //console.log("\n",data,"\n",concatenatedData,"\n");
                            }
                        });
                    });

// try and set the data here (since you're using for each, you will need to check index and length so you only set it once)

// Processing collection items
                    res.items.forEach(item => {
                        // Constructing the concatenated string with line breaks
                        let concatenatedData = `${item.award}\n${item.festival}`;
                        if (item.city) concatenatedData += `\n${item.city}`;
                        if (item.year) concatenatedData += ` ${item.year}`;

                        // Updating text in the repeater
                        $w('#repeaterAwards').onItemReady(($item, data) => {
                            if (data._id === item._id) {
                                $item('#award').text = concatenatedData;
                                //console.log("\n",data,"\n",concatenatedData,"\n");
                            }
                        });
if (index === res.items.length -1 ) $w('#repeaterAwards').data = res.items
                    });

1 Like

Thanks for your help !

The reason I don’t fill the data directly into the repeater is because it must first be concatenated to display in a single text field rather than in a stack.

I modified the code like this and it finally works:

import wixData from 'wix-data';

$w.onReady(function () {
    // Wait for the dataset to be ready
    $w('#dataset2').onReady(() => {
        // Loading data from the "Awards" collection with a filter and a limit of 10 items
        wixData.query("Awards")
            .eq("type", "Prix")  // Filter data where the "type" field is equal to "Prix"
            .limit(10)           // Limit the number of items to 10
            .find()
            .then(res => {
                // Set the data for the repeater with the retrieved items
                $w('#repeaterAwards').data = res.items;

                // Use onItemReady to update each element in the repeater
                $w('#repeaterAwards').onItemReady(($item, itemData, index) => {
                    // Constructing the concatenated string with line breaks
                    let concatenatedData = `${itemData.award}\n${itemData.festival}`;
                    if (itemData.city) concatenatedData += `\n${itemData.city}`;
                    if (itemData.year) concatenatedData += ` ${itemData.year}`;

                    // Update the text of the repeater element
                    $item('#award').text = concatenatedData;
                });
            })
            .catch(err => {
                // Handle any errors that may occur during the data retrieval
                console.error(err);
            });
    });
});