Skip to content

Fixes reload and refresh not updating internal completer#395

Open
davidmartos96 wants to merge 3 commits intorodydavis:mainfrom
davidmartos96:fix_reload_refresh
Open

Fixes reload and refresh not updating internal completer#395
davidmartos96 wants to merge 3 commits intorodydavis:mainfrom
davidmartos96:fix_reload_refresh

Conversation

@davidmartos96
Copy link

@davidmartos96 davidmartos96 commented May 4, 2025

Legacy PR

Fixes #394

The problem was that the equality in AsyncState wasn't being done properly when going from AsyncDataReloading to AsyncData because as a side effect to the reloading state being a subclass of AsyncData. I've added the equality with the 3 loading states. I think that would be the correct solution for the exhaustiveness.

Additionally, while creating a test, I've noticed that a future signal .reload() wasn't propagating the reload future because the internal Completer wasn't being recreated.

image

For this, would it be ok to remove the batch? I've added it because it is how it's written in setValue, but I'm not sure it's needed.

The PR updates some tests to prevent regression on issue #394 . Additionally, it makes sure that the async signals update their internal Completer instance when calling reload()/refresh(), otherwise, the value of the future returned by signal.reload() will be referring to the Future before reload() was called.

Future<void> reload() async {
await super.reload();
await future;
}

@alfonsovgs
Copy link

@davidmartos96 The same thing happened to me, how did you solve it without that change?

@davidmartos96
Copy link
Author

@alfonsovgs I wasn't able to solve it without this. @rodydavis mentioned in the linked issue that it works as expected though. To me it makes much more sense the behavior with the proposed changes.

@alfonsovgs
Copy link

@alfonsovgs I wasn't able to solve it without this. @rodydavis mentioned in the linked issue that it works as expected though. To me it makes much more sense the behavior with the proposed changes.

I think the same. For now, I did this and it works, as I understand Signals a little better.

class NonDistinct<T> {
  const NonDistinct(this.value);

  final T value;

  @override
  bool operator ==(Object other) => false;

  @override
  int get hashCode => identityHashCode(this);
}
final currentLocation = futureSignal<NonDistinct<LatLng?>>(() async {
  await Future.delayed(Durations.short4);
  return LatLng(40.73061, -73.9);
}, debugLabel: 'currentLocation');

@davidmartos96
Copy link
Author

I still believe something else could be changed. Even with the equality added, the signal isn't properly updating when going from reloading to data.

@rodydavis
Copy link
Owner

I think something that would help me in reviewing this, would be a detailed explainer on the expected behavior. Maybe a mermaid graph with the states?

@davidmartos96
Copy link
Author

@rodydavis
After some investigation, it looks like the package is behaving as expected in the latest main commit.

My expectation was the following after using reload(). Take the following signal as an example:

final myAsyncSignal = futureSignal<int>(() async {
  await Future.delayed(Duration(milliseconds: 2000));
  return 10;
});
EXPECTED
2025-11-30 17:28:59.997716: AsyncData<int>  isLoading: false  isReloading: false
2025-11-30 17:29:03.276336: Reload tapped
2025-11-30 17:29:03.278430:  (immediate after reload) AsyncDataReloading<int>  isLoading: true  isReloading: true
2025-11-30 17:29:05.291864: (2 seconds later) AsyncData<int>  isLoading: false  isReloading: false 
HOW IT WAS BEHAVING BEFORE
2025-11-30 17:28:59.997716: AsyncData<int>  isLoading: false  isReloading: false
2025-11-30 17:29:03.276336: Reload tapped
2025-11-30 17:29:03.278430:  (immediate after reload) AsyncDataReloading<int>  isLoading: true  isReloading: true
(no AsyncData is returned, forever in the reloading state)

It turns out that it was fixed in 6d8c4c2 by changing equalityCheck in Signal from (T a, T b) => a == b; to identical

If this is expected, I can update the PR to just reuse the test cases, I believe they should work now with the current behavior.

@davidmartos96 davidmartos96 changed the title Fixes reload and refresh not setting loading to false after completing Fixes reload and refresh not updating internal completer Nov 30, 2025
@rodydavis
Copy link
Owner

Yep the latest commit should be correct now!

@davidmartos96
Copy link
Author

@rodydavis What do you think about the proposed tests and minor fix for the refresh() and reload() completers?

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.

Future signal refresh/reload state is still loading even when the data is returned

3 participants