Open Giuspepe opened 1 year ago
Hi @Giuspepe did you find any workaround for this issue ?
Hi @Giuspepe did you find any workaround for this issue ?
Sorry @sagnik-sanyal, I don't remember looking into this any further as it was a year ago
Thanks man for your quick response
Upvoted this issue , current workaround is to use synchronous validators instead of async validator. @joanpablo Looking forward to hear from you regarding this.
When using a
ReactiveFormArray
withasyncValidators
in itsFormArray
, the builder doesn't update when theFormArray.status
changes frompending
tovalid
due to theasyncValidators
. Instead, it is stuck inpending
even though theasyncValidators
return immediately. If I remove theasyncValidators
and only use synchronousvalidators
, it works as expected.See the attached screen recording and minimum reproducible example.
When using a
ReactiveFormArray
with aFormArray
which hasasyncValidators
, I expectReactiveFormArray.builder
to be rebuilt when theFormArray.status
changes due to theasyncValidators
.https://user-images.githubusercontent.com/39117631/217793024-093049d2-675e-4ec1-849a-3fff9504017d.mp4
You can see that the
FormArray.status
does indeed change back to valid if I accessFormArray.status
in aStreamBuilder
listening toFormArray.statusChanged
. It's just theReactiveFormArray.builder
that doesn't receive the newFormArray.status
. Compare theformArray.status
Texts in the video in red (FormArray.status
inStreamBuilder
) and black (FormArray.status
inReactiveFormArray.builder
). The black text stays atControlStatus.pending
whenasyncValidators
are enabled while it should be in sync with the red text.main.dart
```dart import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:reactive_forms/reactive_forms.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return const ProviderScope( child: MaterialApp( title: 'Flutter Demo', home: MyHomePage(), ), ); } } class MyHomePage extends ConsumerWidget { const MyHomePage({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { final formArray = ref.read(myControllerProvider.notifier).formArray; return Scaffold( appBar: AppBar( title: const Text('Demo'), ), body: Center( child: ReactiveFormArray( formArray: formArray, builder: (context, formArray, _) => SingleChildScrollView( child: Column( mainAxisAlignment: MainAxisAlignment.center, children:> { MyController() : super([]); void update() => state = [...state, DateTime.now()]; void setAsyncValidators() { formArray.setAsyncValidators(_asyncValidators, autoValidate: true); formArray.markAllAsTouched(); } void clearAsyncValidators() { formArray.clearAsyncValidators(); // formArray.clearAsyncValidators states: // When you add or remove a validator at run time, you must call // **updateValueAndValidity()** for the new validation to take effect. formArray.updateValueAndValidity(); formArray.markAllAsTouched(); } late final formArray = FormArray(
[],
validators: _validators,
asyncValidators: _asyncValidators,
);
final _validators = [Validators.minLength(4)];
final _asyncValidators = [_asyncValidator];
}
Future
pubspec.yaml
``` name: reactive_forms_example environment: sdk: '>=2.19.0 <3.0.0' dependencies: flutter: sdk: flutter cupertino_icons: ^1.0.2 reactive_forms: ^14.2.0 flutter_riverpod: ^2.1.3 ```