-
-
Notifications
You must be signed in to change notification settings - Fork 977
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
selectAsync does not update immediately after invalidate #3959
Comments
Considering T refresh<T>(provider) {
invalidate(provider);
return read(provider);
} Then there's something else going on. But thanks for taking the time to write tests! I'll look into it :) |
Glad to see more folks are writing tests directly in their issues 😄 I reproduced the whole case and added the corresponding label; I also want to add this failing test to the previous suite: test('watch-selectAsync invalidate microtask', () async {
await expectLater(
container.read(baseAreaSelectAsyncProvider.future),
completion(153.93804002589985),
);
container.invalidate(coneProvider);
await Future.microtask(() {}); // instead of a delay
await expectLater(
container.read(baseAreaSelectAsyncProvider.future),
completion(254.46900494077323), // still 153.93804002589985
);
}); Finally, for convenience, here are all the tests clustered together, with no codegen involved. Full Reproimport 'dart:math';
import 'package:riverpod/riverpod.dart';
import 'package:test/test.dart';
final randomProvider = Provider<Random>((ref) {
return Random(1);
});
final coneProvider = FutureProvider<({int h, int r})>((ref) async {
final random = ref.watch(randomProvider);
final cone = (
h: random.nextInt(10),
r: random.nextInt(10)
); // (h: 4, r: 7), (h: 5, r: 9), ...
return cone;
});
final baseAreaSelectAsyncProvider = FutureProvider<double>((ref) async {
final r = await ref.watch(coneProvider.selectAsync((c) => c.r));
return r * r * pi;
});
final baseAreaProvider = FutureProvider<double>((ref) async {
final (h: _, r: r) = await ref.watch(coneProvider.future);
return r * r * pi;
});
void main() {
late ProviderContainer container;
setUp(() {
container = ProviderContainer();
});
test('watch-selectAsync invalidate', () async {
await expectLater(
container.read(baseAreaSelectAsyncProvider.future),
completion(153.93804002589985),
);
container.invalidate(coneProvider);
await expectLater(
container.read(baseAreaSelectAsyncProvider.future),
completion(254.46900494077323), // Failed, actual 153.93804002589985
);
});
test('watch-selectAsync refresh', () async {
await expectLater(
container.read(baseAreaSelectAsyncProvider.future),
completion(153.93804002589985),
);
await container.refresh(coneProvider.future);
await expectLater(
container.read(baseAreaSelectAsyncProvider.future),
completion(254.46900494077323),
);
});
test('watch-selectAsync invalidate delay', () async {
await expectLater(
container.read(baseAreaSelectAsyncProvider.future),
completion(153.93804002589985),
);
container.invalidate(coneProvider);
await Future.delayed(Duration.zero);
await expectLater(
container.read(baseAreaSelectAsyncProvider.future),
completion(254.46900494077323),
);
});
test('watch-selectAsync invalidate microtask', () async {
await expectLater(
container.read(baseAreaSelectAsyncProvider.future),
completion(153.93804002589985),
);
container.invalidate(coneProvider);
await Future.microtask(() {}); // instead of a delay
await expectLater(
container.read(baseAreaSelectAsyncProvider.future),
completion(254.46900494077323), // still 153.93804002589985
);
});
test('watch invalidate', () async {
await expectLater(
container.read(baseAreaProvider.future),
completion(153.93804002589985),
);
container.invalidate(coneProvider);
await expectLater(
container.read(baseAreaProvider.future),
completion(254.46900494077323),
);
});
test('watch refresh', () async {
await expectLater(
container.read(baseAreaProvider.future),
completion(153.93804002589985),
);
await container.refresh(coneProvider.future);
await expectLater(
container.read(baseAreaProvider.future),
completion(254.46900494077323),
);
});
tearDown(() {
container.dispose();
});
} |
Describe the bug
I encountered an issue when using selectAsync with invalidate().
The provider using watch updates as expected, but the provider using selectAsync does not update immediately after invalidate().
To Reproduce
Expected behavior
When coneProvider is invalidated, calling container.read(baseAreaSelectAsyncProvider.future) should immediately return the updated value.
The text was updated successfully, but these errors were encountered: