Repeater not displaying data when using .group()

Using the following code to populate a repeater. The onItemReady gets called when I have the .group() commented out and displays the correct total in the $item(“#remainBal”) element. However, when the .group() is active onItemReady is not called but the resulting data is correct and in the correct structure.

let balTtl = [];

$w.onReady(async function () {
    fillDropdown()
    getClientList()
    await clientBalances()
    

});


export async function clientBalances() {
    //const filter = wixData.filter().eq("invoiceNumber", invNum);
    balTtl = [];
    balTtl = await wixData.aggregate("ClientLedgers")
        //.filter(filter)
        .group("client")
        .sum("amounts", "remainBal")
        .descending("remainBal")
        .run()
        .then((results) => {
            return results.items;
        })
    
    $w("#clientBal").onItemReady(($item, itemData, index) => {
        console.log("Item ready", index, itemData);
        $item("#companyName").text = itemData.client;
        $item("#remainBal").text = itemData.remainBal.toLocaleString('en-US', { style: 'currency', currency: 'USD' });
    });
    $w("#clientBal").data = balTtl;
    console.log(balTtl);

}

I’m using Wix Editor.

There are no empty records for ‘client’ and again, when I console.log the data it’s correctly structured with valid values.

This could be because of server side rendering then. It’s being rendered on the server before it gets to the client so you don’t see $w.onReady being called.

Any suggestions on how to fix?

Ohh I misunderstood “the resulting data is correct”. There are two things you can try:

Might also want to make sure your repeater isn’t attached to a dataset in the UI. If items are pre-populated in the repeater and then those same items are updated in your code then onItemReady won’t be called for them.

made the recommended changes and checked to make sure repeater is not connected to a dataset. Still no data displayed in the repeater and .onItemReady not being called.

I still think it has something to do with the .group() function in the aggregate. When I comment out //.group and preview the page, the repeater is populated with the correct sum of all amounts. Any ideas why this method would cause this?

SOLVED!

Turns out that the balTtl[0]._id must be the index of the item and as a string. i.e.

[{“client”: “Name”,“remainBal”: 123,“_id”:“0”},{…etc}].

shouldn’t the group() function write the _id as an index instead of using the field value?

Ohh I see. Great catch!

That is interesting. I’m almost certain I’ve used Repeaters before where the _id is either a uuid or an arbitrary string. Will need to investigate more.

Following up on this. It seems that when aggregating _id becomes the closest JS type of whatever column is being aggregated. So Number -> number and Text -> string. However when _id is a number it doesn’t work with a Repeater.

For anyone else reading along the workaround for this is to do the items.map() demonstrated below. In this example the column we’re aggregating (ie. year) is a Number and so its _id will be a number like 2021 and this needs to be a string to work with a Repeater.

import wixData from 'wix-data';

$w.onReady(function () {
    wixData.aggregate("Sales")
        .group("year")
		.sum("amount")
        .run().then((results) => {
            let items = results.items;
            items = items.map((i) => {
                i._id = i._id.toString();
                return i;
            });
            $w('#repeaterYear').data = items;
        })
});

Edit: For future reference here is an article that goes into detail on what _ids are valid for Repeaters: Working with Repeaters - Velo API Reference - Wix.com