Skip to content

Bug / Enhancement: Fix unstable sorting & enforce nulls at bottom #9311

@tobiu

Description

@tobiu

Sorting columns with mapped data and missing values (like company in DevIndex) resulted in unstable, varying sort orders that seemingly "improved" the more times a sort was triggered.

This occurred due to two overlapping issues:

  1. Soft Hydration Inconsistency: Neo.data.Store#resolveField was returning undefined for missing mapped keys on raw objects, while fully hydrated records correctly received their defaultValue (e.g., null).
  2. JavaScript Sorting Transitivity: Neo.collection.Base and Neo.collection.Sorter relied on standard < and > operators. In JS, null and undefined evaluate as "equal" to strings (both < and > return false), breaking sorting transitivity and causing random scrambling of the array.

This ticket fixes the bug by introducing an enhancement to the framework's sorting paradigm: null and undefined values are now always pushed to the bottom of the collection, regardless of whether the sort direction is ASC or DESC.

Changes:

  • src/data/Store.mjs: Updated resolveField() to apply defaultValue if the raw value is undefined.
  • src/collection/Base.mjs: Added explicit == null isolation logic to doSort() to always push null/undefined values to the bottom.
  • src/collection/Sorter.mjs: Added explicit == null isolation logic to defaultSortBy() to always push null/undefined values to the bottom.
  • test/playwright/unit/collection/SortNull.spec.mjs: Added a new unit test to explicitly verify this behavior.

Metadata

Metadata

Assignees

Labels

aibugSomething isn't workingcoreCore framework functionalityenhancementNew feature or request

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions