Flutter : initial value not updating in Form (FormBuilder)

3.4k Views Asked by At
 _updatePersonalFormScreen(String loginId) async {
    if (!DartUtility.isNullEmptyOrWhitespace(loginId)) {
      _personalInfo = await _service.getUserPersonalDetails(loginId);
      setState(() {
        if (_personalInfo != null) {
          if(!DartUtility.isNullEmptyList(_personalInfo.getContacts())){
            contactList = _personalInfo.getContacts();
          }     
          personalInfoMap = _personalInfo.toPersonalInfoMap();
        }
        print('personalInfo retrieved object ${_personalInfo.toString()}');   //1
      });
    }     
  }

formBuilder widget :

  FormBuilder buildFormBuilder(BuildContext context) {
    print('personalInfoMap $personalInfoMap');         //2
    return FormBuilder(
          key: _personalDetailFormKey,
          initialValue: personalInfoMap,               //3
          autovalidate: true,
          child: Stack(),
        );
  }

//line-1 and line-2 printing correct values but at line-3, the initial values are not getting assigned to the form builder textbox

'contactList' is populating correctly and in the same block populating 'personalInfoMap' not working properly as expected or may value assigned at line-3 need some thing else to be modified to make it work

I have tried working with Future builder as well but no luck. If 'contactList' is working fine and assigned to the form values, so why facing issue in other field ? :(

Could someone please help me on this, What else need to be done here and where its getting wrong.

3

There are 3 best solutions below

0
On

After 4 5 hour struggle, able to resolved finally, and the saviour is 'Future builder'. here is the solution,

Instead of directly calling FormBuilder in build method, wrap it inside FutureBuilder

@override
  Widget build(BuildContext context) =>SafeArea(
        child: Scaffold(
          body: Container(
            height: MediaQuery.of(context).size.height,
            child: FutureBuilder(
              future: _getPersonalInfoFormInitialValue(),
              builder: (context, snapshot) => snapshot.hasData
                  ? buildFormBuilder(context, snapshot.data) // this provide returned data from _getPersonalInfoFormInitialValue()
                  : const SizedBox(),
            ),
          ),
        ),
      );

Modified formBuilder widget :

FormBuilder buildFormBuilder(BuildContext context, data) {
    print('datat ::::$data');
        return FormBuilder(
          key: _personalDetailFormKey,
          initialValue:data,               //assigned fetched data
          autovalidate: true,
          child: Stack(), 
      );
  }
0
On

It seems like the value initially loaded can't be changed still the _formKey remains in memory. So we need to prevent initializing first time with null

I use reverpod with flutter form following is the relevant code of rough implementation with watch

Widget build(
    BuildContext context,
    ScopedReader watch,
  ) {
    final loginId = context.read(selectedLoginId).state; // user id to check if there is a valid data
        final user = watch(selectedUser).data?.value; // getting user info we need both
       
        return Padding(
          padding: const EdgeInsets.all(32.0),
          child: Column(
            children: [
              (loginId != null && user == null)
                  ? CircularProgressIndicator()
                  : FormBuilder(
              key: _personalDetailFormKey,
              initialValue:user,               //assigned fetched data
              autovalidate: true,
              child: Stack(), 
          ),]));}
0
On

Struggled for a long time but found the solution to form_builder update problem

class _CommonContentFormState extends State<CommonContentForm>
var commonForm = GlobalKey<FormBuilderState>();

@override
Widget build(BuildContext context) {
// Must create new GlobalKey before building form to update
// with new data from Provider...
    commonForm = GlobalKey<FormBuilderState>(); 
    formData = Provider.of<FormData>(context); 
    return SingleChildScrollView(
      padding: EdgeInsets.fromLTRB(0,0,20,0),
        child: FormBuilder(
        key: commonForm,
        .....