skip to Main Content

In one of the script I have bought state of stateful widget is being set and retrieved using Address object. The script is working so I think the approach is not wrong. When I am using same approach and trying to assign and retrieve the value its coming as null (after _formKey.currentState!.save()). Looking forward for some insight from experts.

import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart' show CupertinoIcons;
import 'package:provider/provider.dart';

class Address {
  String? firstName;
  String? lastName;

  void setAddress(Address? address) {
    print(address);
  }
}

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const ShippingAddress(),
    );
  }
}

class ShippingAddress extends StatefulWidget {
  final Function? onNext;

  const ShippingAddress({super.key, this.onNext});

  @override
  State<ShippingAddress> createState() => _ShippingAddressState();
}

class _ShippingAddressState extends State<ShippingAddress> {
  final _formKey = GlobalKey<FormState>();

  Address? address;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Column(
      mainAxisSize: MainAxisSize.min,
      children: [
        Expanded(
          child: SingleChildScrollView(
            child: Padding(
              padding: const EdgeInsets.only(
                left: 16.0,
                right: 16.0,
                bottom: 50.0,
              ),
              child: Form(
                key: _formKey,
                child: AutofillGroup(
                  child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        TextFormField(
                          /// Auto focus first field if it's empty.
                          onSaved: (value) => onTextFieldSaved(
                            value,
                            'first_name',
                          ),
                        )
                      ]),
                ),
              ),
            ),
          ),
        ),
        Row(
          mainAxisSize: MainAxisSize.min,
          children: [
            SizedBox(
              width: 150,
              child: OutlinedButton.icon(
                style: OutlinedButton.styleFrom(padding: EdgeInsets.zero),
                onPressed: () {
                  _formKey.currentState!.save();
                  // Provider.of<Address>(context, listen: false)
                  //     .setAddress(address);
                  print(address);
                },
                icon: const Icon(
                  CupertinoIcons.plus_app,
                  size: 20,
                ),
                label: const Text(
                  "Save",
                ),
              ),
            ),
            Container(width: 8),
            Expanded(
              child: ElevatedButton.icon(
                style: ElevatedButton.styleFrom(
                  foregroundColor: Colors.white,
                  backgroundColor: Theme.of(context).primaryColor,
                  elevation: 0.0,
                  padding: EdgeInsets.zero,
                ),
                icon: const Icon(
                  Icons.local_shipping_outlined,
                  size: 18,
                ),
                onPressed: () {
                  _formKey.currentState!.save();
                  // Provider.of<Address>(context, listen: false)
                  //     .setAddress(address);
                  print(address);
                },
                label: const Text("Next"),
              ),
            ),
          ],
        ),
      ],
    ));
  }

  void onTextFieldSaved(String? value, String type) {
    switch (type) {
      case 'first_name':
        address?.firstName = value;
        break;
    }
  }
}

2

Answers


  1. Chosen as BEST ANSWER

    @CStark answer made my day. Even though I was just missing 1 simple line of code, after adding it everything started working as expected. Here I am posting my working code. @CStark let me know brother if I can buy you a coffee :)

    import 'package:flutter/material.dart';
    import 'package:flutter/cupertino.dart' show CupertinoIcons;
    import 'package:provider/provider.dart';
    
    class Address {
      String? firstName;
      String? lastName;
    
      void setAddress(Address? address) {
        print(address);
      }
    }
    
    void main() {
      WidgetsFlutterBinding.ensureInitialized();
      runApp(const MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({super.key});
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
            useMaterial3: true,
          ),
          home: const ShippingAddress(),
        );
      }
    }
    
    class ShippingAddress extends StatefulWidget {
      final Function? onNext;
    
      const ShippingAddress({super.key, this.onNext});
    
      @override
      State<ShippingAddress> createState() => _ShippingAddressState();
    }
    
    class _ShippingAddressState extends State<ShippingAddress> {
      final _formKey = GlobalKey<FormState>();
    
      Address? address;
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
            body: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            Expanded(
              child: SingleChildScrollView(
                child: Padding(
                  padding: const EdgeInsets.only(
                    left: 16.0,
                    right: 16.0,
                    bottom: 50.0,
                  ),
                  child: Form(
                    key: _formKey,
                    child: AutofillGroup(
                      child: Column(
                          crossAxisAlignment: CrossAxisAlignment.start,
                          children: [
                            TextFormField(
                              /// Auto focus first field if it's empty.
                              onSaved: (value) => onTextFieldSaved(
                                value,
                                'first_name',
                              ),
                            )
                          ]),
                    ),
                  ),
                ),
              ),
            ),
            Row(
              mainAxisSize: MainAxisSize.min,
              children: [
                SizedBox(
                  width: 150,
                  child: OutlinedButton.icon(
                    style: OutlinedButton.styleFrom(padding: EdgeInsets.zero),
                    onPressed: () {
                      _formKey.currentState!.save();
                      // Provider.of<Address>(context, listen: false)
                      //     .setAddress(address);
                      print(address!.firstName);
                    },
                    icon: const Icon(
                      CupertinoIcons.plus_app,
                      size: 20,
                    ),
                    label: const Text(
                      "Save",
                    ),
                  ),
                ),
                Container(width: 8),
                Expanded(
                  child: ElevatedButton.icon(
                    style: ElevatedButton.styleFrom(
                      foregroundColor: Colors.white,
                      backgroundColor: Theme.of(context).primaryColor,
                      elevation: 0.0,
                      padding: EdgeInsets.zero,
                    ),
                    icon: const Icon(
                      Icons.local_shipping_outlined,
                      size: 18,
                    ),
                    onPressed: () {
                      _formKey.currentState!.save();
                      // Provider.of<Address>(context, listen: false)
                      //     .setAddress(address);
                      print(address!.firstName);
                    },
                    label: const Text("Next"),
                  ),
                ),
              ],
            ),
          ],
        ));
      }
    
      void onTextFieldSaved(String? value, String type) {
        address = Address(); // missing line of code
    
        switch (type) {
          case 'first_name':
            address?.firstName = value;
            break;
        }
      }
    }
    

  2. A couple of things

    • not creating an instance of address
    • not setting state when value changes
    • missing class constructor

    I put comments on the lines changed

    import 'package:flutter/material.dart';
    import 'package:flutter/cupertino.dart' show CupertinoIcons;
    import 'package:provider/provider.dart';
    
    class Address {
      String? firstName;
      String? lastName;
    
      Address({ this.firstName, this.lastName }) // NEW CHANGE
    
      void setAddress(Address? address) {
        print(address);
      }
    }
    
    void main() {
      WidgetsFlutterBinding.ensureInitialized();
      runApp(const MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({super.key});
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
            useMaterial3: true,
          ),
          home: const ShippingAddress(),
        );
      }
    }
    
    class ShippingAddress extends StatefulWidget {
      final Function? onNext;
    
      const ShippingAddress({super.key, this.onNext});
    
      @override
      State<ShippingAddress> createState() => _ShippingAddressState();
    }
    
    class _ShippingAddressState extends State<ShippingAddress> {
      final _formKey = GlobalKey<FormState>();
    
      Address address = new Address(); // NEW CHANGE
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
            body: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            Expanded(
              child: SingleChildScrollView(
                child: Padding(
                  padding: const EdgeInsets.only(
                    left: 16.0,
                    right: 16.0,
                    bottom: 50.0,
                  ),
                  child: Form(
                    key: _formKey,
                    child: AutofillGroup(
                      child: Column(
                          crossAxisAlignment: CrossAxisAlignment.start,
                          children: [
                            TextFormField(
                              /// Auto focus first field if it's empty.
                              onSaved: (value) => onTextFieldSaved(
                                value,
                                'first_name',
                              ),
                            )
                          ]),
                    ),
                  ),
                ),
              ),
            ),
            Row(
              mainAxisSize: MainAxisSize.min,
              children: [
                SizedBox(
                  width: 150,
                  child: OutlinedButton.icon(
                    style: OutlinedButton.styleFrom(padding: EdgeInsets.zero),
                    onPressed: () {
                      _formKey.currentState!.save();
                      // Provider.of<Address>(context, listen: false)
                      //     .setAddress(address);
                      print(address);
                    },
                    icon: const Icon(
                      CupertinoIcons.plus_app,
                      size: 20,
                    ),
                    label: const Text(
                      "Save",
                    ),
                  ),
                ),
                Container(width: 8),
                Expanded(
                  child: ElevatedButton.icon(
                    style: ElevatedButton.styleFrom(
                      foregroundColor: Colors.white,
                      backgroundColor: Theme.of(context).primaryColor,
                      elevation: 0.0,
                      padding: EdgeInsets.zero,
                    ),
                    icon: const Icon(
                      Icons.local_shipping_outlined,
                      size: 18,
                    ),
                    onPressed: () {
                      _formKey.currentState!.save();
                      print(address);
                    },
                    label: const Text("Next"),
                  ),
                ),
              ],
            ),
          ],
        ));
      }
    
      void onTextFieldSaved(String? value, String type) {
        Address _address = new Address(); // NEW CHANGE
        switch (type) {
          case 'first_name':
            address?.firstName = value;
            break;
        }
    
        // NEW CHANGE
        setState(() {
          address = _address;
        })
      }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search