supabase-community/flutter-auth-ui

Metadata Fields in SupaEmailAuth Widget Losing Values

Closed this issue · 0 comments

Describe the bug

I have a MetaDataField on my SupaEmailAuth sign up form that I use for usernames, but on form submission the value of this field would be an empty string:

MetaDataField(
  prefixIcon: const Icon(Icons.person),
  label: 'Username',
  key: 'username',
  validator: (val) {
     if (val == null || val.isEmpty) {
       return 'Please enter a username';
     }
     return null;
   },
),

When I set a breakpoint inside the validator function, val contained the correct value (which is why it wasn't blocking form submission), but when I peeked inside the SupaEmailAuth widget, the text property of the TextEditingController for the username field would be an empty string.

Text controllers for the email and password fields are initialized in the constructor, but the ones for MetaDataFields are marked late and initialized in initState(), like this:

  @override
  void initState() {
    super.initState();
    _metadataControllers = Map.fromEntries((widget.metadataFields ?? []).map(
        (metadataField) => MapEntry(metadataField, TextEditingController())));
  }

In the build() function, the controllers are passed in like this:

                ...widget.metadataFields!
                    .map((metadataField) => [
                          TextFormField(
                            controller: _metadataControllers[metadataField],

Upon closer inspection, metadataField and _metadataControllers[0] appeared to be identical, but had different hash codes. Because of this, the MetaDataField object being used as a key in the _metadataControllers map is not the same instance as the one I was using to access the controller later.

Claude.ai is (worryingly) a better Flutter dev than I am, and showed me how to fix this (which I will do after filing this). I wrote the above description myself, but Claude has helpfully supplied the following summary of the issue:

TLDR

MetaDataField objects are used as keys in the _metadataControllers map.
MetaDataField class lacks custom implementations for the == operator and hashCode getter.
This causes seemingly identical MetaDataField objects to have different hash codes, leading to mismatches when accessing controllers.