onItemReady not working on repeater update

#repeater #onItemReady #save

I have a repeater with an onClick assigned to each item container. The onClick passes the repeater data to a lightbox where you can update the itemData for the clicked item. The updates are saved to the database, the repeater data array is updated with the changes, sent back to the page, the repeater is cleared using $w(“#applicationsRepeater”).data = and then the repeater data is set to the amended array. I would then expect the onItemReady to fire. The problem is, for the updated item (which logs corretly in the console with the decision paramater showing for the updated item), the $item(“#decisionBox”) i s not shown, nor is the backgroundColor updated.

Here is my code:

 $w('#applicationsRepeater').onItemReady(($item, itemData, index) => {
                $item('#text14').text = itemData.title
                if (itemData.decision) {
                    $item("#decisionBox").show().then(() => {
                        $item('#decision').text = itemData.decision
                        if (itemData.decision == "Refused") {
                            $item("#decisionBox").style.backgroundColor = "#f66384"
                        } else if (itemData.decision == "Withdrawn") {
                            $item("#decisionBox").style.backgroundColor = "#F2BD6C"
                        } else if (itemData.decision == "Approved") {
                            $item("#decisionBox").style.backgroundColor = "#5CA283"
                        }
                    })
                } else {
                    $item("#decisionBox").hide()
                }
                
                $item("#application").onClick((event) => {
                    let dataObj = {
                        "itemData": itemData,
                        "repeaterData": $w('#applicationsRepeater').data,
                        "project": selectedProject
                    }

                    wixWindow.openLightbox("Application", dataObj)
                        .then((data) => {
                            if (data) {
                                $w("#applicationsRepeater").data = []
                                let receivedData = data;
                                console.log(receivedData)
                                return receivedData
                            }
                        })
                        .then((receivedData) => {
                            $w("#applicationsRepeater").data = receivedData

                        })

                });

            })

Can’t see any reason why the onItemReady would cause the $item(“#decisionBox”) to show where the updated object in the array contains the decision parameter. If I refresh the page, the box is shown for the updated item.

I had originally thought it wasn’t firing because the _id of the updated item was already in the array, but I would expect that clearing the repeater data and then setting it to the updated array would solve this. See screenshot following setting the repeater data. I would expect another yellow box.

Help appreciated.

Having an event handler inside the repeater.onItemReady is considered bad practice and might cause problems if you change the repeater items.

Go to the NPM’s (not the Velo packages). serach for ‘repeater-scope’.
Install it and follow the instructions in the readme file.

Updating an item does not run the onItemReady it only runs when a new item is added (or thats what i think how it works).
What i do is,
When the data is changed in the repeaterItem
add repeaterdata to a variable,
then clear the repeater
add the variable to the repeaterData.
So something like this
var data = $w ( ‘#applicationsRepeater’ ).data
$w ( ‘#applicationsRepeater’ ).data = []
$w ( ‘#applicationsRepeater’ ).data = data
By clearing it, and adding the data again it will run the onItemReady code.

Hope this helps.

Kind regards,
Kristof.

Thanks for the info - I have removed the event handler from the onReady (and will continue to in future) but it hasn’t solved the issue I have described

Thanks Kristof. Yes - you are correct that this is how it works. If the id already exists in the repeater then the onItemReady is not triggered for that item. In my code above, I do clear the repeater by setting $w ( “#applicationsRepeater” ). data = []

After that, I set the repeater data to the amended array which is received from the lightbox. I would expect the onItemReady event handler therefore to trigger for all items as they are all new following the $w ( “#applicationsRepeater” ). data = []

The issue is, it doesn’t seem to work as expected.

@iaindowner post your new code and we will see.

@jonatandor35 this is my updated code which sits within $w.onReady.

 $w('#applicationsRepeater').onItemReady(($item, itemData, index) => {
                        $item('#text14').text = itemData.title
                        if (itemData.decision) {
                            $item("#decisionBox").show().then(() => {
                                $item('#decision').text = itemData.decision
                                if (itemData.decision == "Refused") {
                                    $item("#decisionBox").style.backgroundColor = "#f66384"
                                } else if (itemData.decision == "Withdrawn") {
                                    $item("#decisionBox").style.backgroundColor = "#F2BD6C"
                                } else if (itemData.decision == "Approved") {
                                    $item("#decisionBox").style.backgroundColor = "#5CA283"
                                }
                            })
                        } else {
                            $item("#decisionBox").hide()
                        }

                    })

                    $w('#application').onClick((event) => {
                        updateItem(event, ($item, itemData, index) => {
                            let dataObj = {
                                "itemData": itemData,
                                "repeaterData": $w('#applicationsRepeater').data,
                                "project": selectedProject
                            }

                            wixWindow.openLightbox("Application", dataObj)
                                .then((data) => {
                                    if (data) {
                                        $w("#applicationsRepeater").data = []
                                        let receivedData = data;
                                        console.log(receivedData)
                                        return receivedData
                                    }
                                })
                                .then((receivedData) => {
                                    $w("#applicationsRepeater").data = receivedData
                                })
                        });
                    });

I am also doing import { updateItem } from ‘repeater-scope’;

@iaindowner I think useScope is what you need.

@jonatandor35 So now i am importing useScope and adding the following onClick event handler to the repeated item container:

export function application_click(event) {
    const { $item, itemData, index, data } = useScope(event);
    let dataObj = {
        "itemData": itemData,
        "repeaterData": data,
        "project": selectedProject
    }

    wixWindow.openLightbox("Application", dataObj)
        .then((data) => {
            if (data) {
                $w("#applicationsRepeater").data = []
                let receivedData = data;
                console.log(receivedData)
                return receivedData
            }
        })
        .then((receivedData) => {
            $w("#applicationsRepeater").data = receivedData
        })
}

The result is still the same as I described in the original post.

@iaindowner
Move the following line to the first .then(() => {} block and remove the second .then():

$w("#applicationsRepeater").data = receivedData;

Also make sure all the items you retrieve from the lightbox have a unique _id value (I can’t see if the 3rd item you logged to the console has it or not)

@iaindowner another thing.
When you send the data from the lightbox try to do it like that:
Lightbox:

wixWindow.lightbox.close({data: dataArray});

and on the main page:

.then(dataObj => {
if(dataObj){
 $w("#applicationsRepeater").data = dataObj.data;
 })
})

@jonatandor35 Code amended to:

export function application_click(event) {
    const { $item, itemData, index, data } = useScope(event);
    let dataObj = {
        "itemData": itemData,
        "repeaterData": data,
        "project": selectedProject
    }

    wixWindow.openLightbox("Application", dataObj)
        .then((data) => {
            if (data) {
                $w("#applicationsRepeater").data = []
                let receivedData = data;
                console.log(receivedData)
                $w("#applicationsRepeater").data = receivedData
            }
        })

}

Issue persists. Below console shows receivedData. The application named Test 2 has been updated with the decision paramater. Given the repeater data is set to and then to receivedData, I would expect the onItemReady to fire (as per my original post) and the decision box to show.

Additionally, I have even tried to add a forEachItem which mirrors the onItemReady and trigger it after the repeater data is set to receivedData but I see the same issue. You can also see that both items have unique _ids.

@jonatandor35 I’ve also tried sending as you suggest:

wixWindow.lightbox.close({data: dataArray});

Unfortunately, it doesn’t resolve the problem.