Skip to content

Fix: asyncListCallback called at initState#180

Merged
koukibadr merged 2 commits into
koukibadr:mainfrom
julien-levarlet:fix/async_initial_list
May 30, 2026
Merged

Fix: asyncListCallback called at initState#180
koukibadr merged 2 commits into
koukibadr:mainfrom
julien-levarlet:fix/async_initial_list

Conversation

@julien-levarlet
Copy link
Copy Markdown
Contributor

@julien-levarlet julien-levarlet commented May 29, 2026

Closes #179.

The SearchableList.async now stores the asyncListCallback result and transmit it as an argument of asyncListFilter as expected.
The example is updated to show this behavior.

Summary by CodeRabbit

  • Bug Fixes
    • Fixed searchable list filtering so it operates on the currently provided data set rather than a stale static reference.
    • Improved async loading and search flow: the component now shows loading during initial fetch, prevents filtering until initial data is ready, and handles concurrent operations more reliably.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 29, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 8744d3ac-dff0-4feb-b17f-5701fc53aaaf

📥 Commits

Reviewing files that changed from the base of the PR and between 69fb484 and 2e8c4fb.

📒 Files selected for processing (1)
  • lib/searchable_listview.dart
🚧 Files skipped from review as they are similar to previous changes (1)
  • lib/searchable_listview.dart

📝 Walkthrough

Walkthrough

SearchableList's async constructor flow is refactored to separate initial data loading from filtering. A new isAsyncCallBackRunning flag tracks initial fetch progress, and a new _asyncInitialList() method handles the initial callback. The example filter callback is corrected to use the provided list parameter instead of a global variable.

Changes

Async Load and Filter Separation

Layer / File(s) Summary
State flag and loading indicator
lib/searchable_listview.dart
New isAsyncCallBackRunning boolean state flag tracks initial async callback progress. Loading widget display condition updated to show loading state during both active filter operations and initial data fetch.
Initial async data loading method
lib/searchable_listview.dart
New _asyncInitialList() method fetches initial data via asyncListCallback, sets error state on failure, toggles isAsyncCallBackRunning flag, and applies or populates results based on current search text. Invoked from initState via addPostFrameCallback.
Filter execution guarding and operation cleanup
lib/searchable_listview.dart
_asyncFilter guards execution to skip while initial async load is running. _activeOperation cleanup in finally block updated to clear only when it matches the completing operation, preventing interruption of concurrent operations. Debounce path adds setState() before canceling operation and awaiting filter.
Example filter callback parameter correction
example/lib/widgets/async_searchable_listview.dart
asyncListFilter callback updated to initialize result from provided list parameter instead of global actors module variable, ensuring filter operates on the current async list.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 I hopped through lists both wide and grand,
Found global crumbs and left my stand.
Now async wakes before the chase,
Filters dance in proper place.
Happy hops — the search runs smooth again!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title concisely describes the main fix: ensuring asyncListCallback is called at initState rather than just _asyncFilter, which aligns with the primary objective.
Linked Issues check ✅ Passed The changes address issue #179 by modifying initState to call asyncListCallback and passing its result to asyncListFilter, resolving the reported problem.
Out of Scope Changes check ✅ Passed All changes are scoped to fixing the async initialization flow in SearchableList; no unrelated modifications detected.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@lib/searchable_listview.dart`:
- Around line 904-909: The catch block in _asyncInitialList calls setState to
set asyncError without checking mounted, which can throw if the widget was
disposed during the prior await; fix by guarding the state update with the
widget's mounted flag (e.g., return early if not mounted or only call setState
when mounted) so the assignment to asyncError occurs only when the State is
still mounted.
- Around line 900-903: The code currently treats a null result from
asyncListCallback() as an empty list; change the logic in the async load path
(where initialData is assigned) to detect a null return from asyncListCallback
and set the error state instead of populating asyncListResult — e.g., after
calling asyncListCallback(), if initialData == null set the error flag/state and
ensure widget.errorWidget will be displayed, otherwise assign initialData to
asyncListResult; update any related state variables and triggers used by the
rendering logic so the error branch (widget.errorWidget) runs when initialData
is null.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 639fcabd-105a-4bfe-b44a-e5e7f875a6fc

📥 Commits

Reviewing files that changed from the base of the PR and between 82bf767 and 69fb484.

📒 Files selected for processing (2)
  • example/lib/widgets/async_searchable_listview.dart
  • lib/searchable_listview.dart

Comment thread lib/searchable_listview.dart
Comment thread lib/searchable_listview.dart
@koukibadr koukibadr merged commit fddc737 into koukibadr:main May 30, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

asyncListCallback never called

2 participants