Structure ->sortBy('branch')->groupBy('branch') one entry missing . what I'm doing wrong?

Hi,

I have a page with a clients structure field. Each client has a branch field.
In my controller I do:

$groupedClients = $page->clients()->toStructure()->sortBy('branch')->groupBy('branch');

In the template I iterate $groupedClients as $branch => $clients and render
each group. The idea: branches alphabetical, clients grouped per branch.

Works for most groups, but one entry is always missing from the first
(alphabetically) branch group.

If I drop the sortBy('branch'):

$groupedClients = $page->clients()->toStructure()->groupBy('branch');

and all entries appear, but the branches aren’t alphabetical sorted anymore.

Minimal example with relevant blueprint part:

clients:
  type: structure
  fields:
    branch:
      type: select
      options:
        a: 'Group A'
        b: 'Group B'
    name:
      type: text

Minimal example with three clients, two share branch a:

Clients:
-
  branch: a
  name: X
-
  branch: b
  name: Y
-
  branch: a
  name: Z
$c = $page->clients()->toStructure();
echo $c->groupBy('branch')->a->count();               // 2 – ok
echo $c->sortBy('branch')->groupBy('branch')->a->count(); // 1 – one missing

Am I using sortBy() before groupBy() wrong? Is there a recommended way to
get the groups in alphabetical order?

Kirby 5.4.0.

By the way, I only noticed this by chance, depending on the data it doesn’t always surface, which is why it took me a while to spot.

Thanks
Robert

Theoretically, it should work fine and does if I test in 5.3.1, still need to test with 5.4.0

Edit: Tried with your simple example in 5.4.0 now, and cannot reproduce your issue.

In home.txt

Title: Home

----

Headline: Welcome to Kirby's Starterkit

----

Subheadline: A fully documented example project

----

Uuid: wljMYhm0m3e9QOwC

----

Clients:
-
  branch: a
  name: X
-
  branch: b
  name: Y
-
  branch: a
  name: Z

In home.php

<?php

$clients = $page->clients()->toStructure()->sortBy('branch')->groupBy('branch');

foreach ($clients as $group => $clients): ?>
    <b><?= 'Group: ' . $group ?> </b>
    
    <?php foreach ($clients as $client): ?>
        <p><?= $client->branch() . ': ' . $client->name() ?></p>
    <?php endforeach ?>

<?php endforeach ?>

Renders:

Hi texnixe,

thanks a lot for the quick test and reply!

I first noticed this on Kirby 4.9.0 and updated to 5.4.0 hoping the issue would be gone, but it persists.

My real project has ~100 clients across 11 different “branch” values, so the small 3-entry example probably isn’t enough to trigger it. It doesn’t reproduce for me at that scale either.

Without the sortBy, groupBy keeps all entries. As soon as I add the sortBy('branch') before the groupBy('branch'), one entry of the alphabetically first branch group disappears.

Could it perhaps be related to the number of elements?

Does each structure item actually have a branch defined?

Ah, I was under the impression that you had reproduced it with the minimal example.

Quick update after some more dumps:

->toStructure() returns all 100 entries with unique sequential keys (0 to 99).

After ->sortBy('branch') all 100 are still there, but the internal keys get reindexed to 0, 1, 2, … in the new sorted order.

After the following ->groupBy('branch') the total item count across all groups drops to 99. The missing entry is always the one that landed at key 0 of the sorted collection.

If I drop the sortBy(), groupBy() keeps all entries (just not alphabetical anymore).

So it seems the combination of sortBy() + groupBy() loses the item at key 0 after the reindexing.

Best
Robert

yes, every item has a “branch” defined. The field is set to `required: true` in the blueprint, and a full dump of the structure shows all 100 entries with a valid branch value (sparte100 to sparte210). And sorry for the confusion. The minimal 3-entry example doesn’t reproduce on my side either. The issue only shows up with my actual dataset (~100 entries across 11 branch values).

Hm, it seems to be really weird. Because even with the same number of items, the number of items actually shown when sorted varies between x and x-1, depending on the branch value assigned to an item. So if the first branch (i.e. first when sorted, a) is at the top of the list, the number of items is correct, whereas when a is put in a later position, it is dropped.

That smells like bug.