Repeater issue. Is it a bug? Is there a solution?

Hi,
Something pretty odd:

let data1 = [{"_id": "a"}, {"_id": "b"}]
let data2 = [{"_id": "b"}, {"_id": "a"}]

as you can see data2 is the reverse order of data1.
Now let’s populate a repeater:

$w("#repeater1").data = data1;
$w("#button1").onClick((event) => {
    $w("#repeater1").data = data2;
})

Once you click the button the items in the reverse order.
So far so good.
But here comes the strange thing. after you clicked the button -

$w("#repeater1").onItemReady( ($item, itemData, index) => {
    $item("#text1").text = itemData._id;
    $item("#text2").text = index.toString();
})

Now despite the fact that the items are ordered in the reversed order as expected, their index inside the onItemReady() function is of the original data (data1).
So the first item to display (id: b) has index 1 while the last item (id: a) has index 0.

Let’s continue:

data2.pop();
$w("#repeater1").data = data2;

Now there’s only 1 item in the repeater (as expected) but… its index === 1 and there’s no item with index 0 at all!
a problem…
Is it a bug? an an annoying feature? Am I doing something wrong?

Thanks,
J.D.

bump

Please post the editor URL of your site. Only authorized Wix personnel can get access to your site in the editor. Please include the name of the page involved.

@yisrael-wix ,
URL: https://editor.wix.com/html/editor/web/renderer/edit/10da34a6-23a2-499a-8bb6-fbede65d0fe2?metaSiteId=21d589c8-180a-4867-99d4-863a60c7a547&editorSessionId=0bddba1d-6af9-423b-91b5-9afb543219a0&referralInfo=my-account

Page name: repeater (which is the homepage).
The question is:
Why doesn’t the index of the repeater items change when I change the source of the repeater data.

Thank you!

J.D.

OK, now this is weird, so hold on to something solid while you’re reading this…

In the onItemReady() API , it states:

The callback is triggered when you add new items by setting the data property. It is not triggered for existing items that are updated when you set the data property.

What you have here is that you’re updating existing items, so the onItemReady() function isn’t being triggered again. You need to force it. What you can do is clear the data, and then set it again. Your onClick() function then would look like this:

    $w("#button1").onClick((event) => {
        $w("#repeater1").data = []; // force onItemReady() to run
        if (option === 1) {
            $w("#repeater1").data = data2;
            option = 2;
        } else {
            $w("#repeater1").data = data1;
            option = 1;
        }
    })

I commented the additional line of code that I added. This additional line of code clears the repeater data so that when you set it again, the items aren’t “updated”, rather they are “new”.

You can let go now. Or perhaps you might need to hold on for just a few moments more.

@yisrael-wix , I see. Thank you.
This solution is problematic because I want to have my cake and eat it too :slight_smile: :
In my real page (not the simple example I linked earlier),
I have a user input field inside the repeater, and I want to keep the input inside an existing item even when I change the order (and that won’t work with your solution)
So, I guess I’ll have to keep the input aside and push it to the relevant item after updating the data source.

At least I know what’s going on.
Thanks a lot!

JD

Well, if you insist on a certain caloric intake, you could use the forEachItem() function. This way you can keep your repeater items intact. However, I’m not sure how that affects the order.

I’ll give it a try. Thank you !