Skip to content
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

[General]: Callback parameters on the current form state in FormBuilder.onChanged() #1430

Open
1 task done
laurisvan opened this issue Sep 20, 2024 · 0 comments
Open
1 task done
Labels
enhancement New feature or request

Comments

@laurisvan
Copy link

Is there an existing issue for this?

  • I have searched the existing issues

Package/Plugin version

7.1.1

What you'd like to happen

Would it be possible to provide a handle to the current form state in FormBuilder.onChanged(), so that the form data could be populated outside the form.

See more context info in the alternatives case and additional information.

Alternatives you've considered

  • Passing the data via GlobalKey (see example below) - we suspect this results in a memory leak when fully repopulating the form and discarding the old key.
  • FormBuilder.of(context) - no handle to the current context is available; if there were - that might be even preferrable, as we probably would not need to declare a GlobalKey. I am not 100% sure if we would be able to retain the state in all cases, though.
  • Register a callback for every widget - this might work, but would be rather tedious alternative.

Aditional information

We use FlutterFormBuilder to add extra fields, specified in JSON Schema. We have created a small factory method that creates a FormBuilder with fields populated based on the JSON Schema. In order to cope with rebuilds, we supply a GlobalKey as a key that we use to populate changes back to our JSON model, and onChanged hook that investigates the contents based on the FormBuilderState.

This works ok, but we have noticed one problem, and suspect another:

  1. When the schema changes to another, the form data are cleaned up, but the widgets are populated with the data from the former schema (even if the keys of the fields are different - it almost looks like the widget values are populated in the same order as in the previous schema)
  2. In order to alleviate the problem, we discard the old key and create a new one and rebuild the FormBuilder so that it would not have any previous state. However, we believe that just throwing away GlobalKeys will result in memory leak (and AFAIK there is no easy means to dispose the widgets and the form builder state without violating Flutter conventions). This gives visually the right result, though.

A sample on how we currently fetch and use the data in our factory that returns an instance of FormBuilder:

      // If no callback was registered, just return
      onChanged: () {
        if (onChanged == null) {
          return;
        }

        // Reform the JSON object from map values. Note that 'instantValue' field will not
        // return correct values prior the call, so we need to the transformation on our own.
        final FormBuilderState state = key.currentState;
        final Map<String, dynamic> value = <String, dynamic>{};

        state.fields.keys.forEach((final String key) {
          final Optional opt = state.fields[key].transformedValue as Optional;
          if (opt?.hasValue ?? false) {
            value[key] = opt.value;
          }
        });

        onChanged(JsonObject(value));
      }
@laurisvan laurisvan added the enhancement New feature or request label Sep 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant