Passing Data From Child To Parent in Flutter- #100DaysOfCode - Day 14

Introduction

This post is part of my 100DaysOfCode series. In this series, I write about my 100DaysOfCode journey. My aim for this challenge is become proficient in flutter and firebase by building an Agriculture Management Information System.

Recap

On Day 13 we discuss how to create a dynamic dropdown form field in flutter.

Overview

In this post, we will discuss how to pass data from a child widget to a parent widget. The region and district dropdown form field will be reused in other forms so they were extracted into its own widget for reusability.

Passing data from child to parent

void _getRegionAndDistrictValue(String region, String district) {
    farmer.saveRegion(region);
    farmer.saveDistrict(district);
  }

The above method will be passed to the RegionDistrictDropdownFormField widget (child widget).

Region District Dropdown FormField

class RegionDistrictDropdownFormField extends StatefulWidget with Validation {
  final Function getDistrictAndRegionValue;

  const RegionDistrictDropdownFormField({
    required this.getDistrictAndRegionValue,
    Key? key,
  }) : super(key: key);

  
  _RegionDistrictDropdownFormFieldState createState() =>
      _RegionDistrictDropdownFormFieldState();
}

class _RegionDistrictDropdownFormFieldState
    extends State<RegionDistrictDropdownFormField> {
  late FocusNode regionFocusNode;
  late FocusNode districtFocusNode;
  List<DropdownMenuItem<String>>? districtDropdownMenuItems;
  String? districtValue;
  String? regionValue;

  
  void initState() {
    regionFocusNode = FocusNode();
    districtFocusNode = FocusNode();
    super.initState();
  }

  
  void dispose() {
    regionFocusNode.dispose();
    districtFocusNode.dispose();
    super.dispose();
  }

  void _handleDropdownOnChanged(FocusNode focusNode) {
    focusNode.requestFocus();
  }

  List<DropdownMenuItem<String>>? _getDistrictItems(String region) {
    late List<DropdownMenuItem<String>> items;

    items = District.byRegion(region)
        .map((e) => DropdownMenuItem(
              child: Text(e),
              value: e,
            ))
        .toList();

    return items;
  }

  
  Widget build(BuildContext context) {
    return Row(
      children: [
        Expanded(
          flex: 5,
          child: DropdownButtonFormField(
            focusNode: regionFocusNode,
            decoration: FormStyles.textFieldDecoration(labelText: 'Region'),
            onChanged: (String? value) {
              setState(() {
                districtDropdownMenuItems = _getDistrictItems(value!);
                regionValue = value;
                districtValue = districtDropdownMenuItems!.first.value;
              });
            },
            validator: widget.validateRequiredField,
            items: Region.all
                .map((e) => DropdownMenuItem(
                      child: Text(e),
                      value: e,
                    ))
                .toList(),
          ),
        ),
        Spacer(),
        Expanded(
          flex: 5,
          child: DropdownButtonFormField(
            focusNode: districtFocusNode,
            decoration: FormStyles.textFieldDecoration(labelText: 'District'),
            onChanged: (String? value) {
              _handleDropdownOnChanged(districtFocusNode);
              districtValue = value;
              widget.getDistrictAndRegionValue(regionValue, districtValue);
            },
            validator: widget.validateRequiredField,
            value: districtValue,
            items: districtDropdownMenuItems,
          ),
        )
      ],
    );
  }
}

When the user selects a district the widget.getDistrictAndRegionValue(regionValue, districtValue) method will be called. This will allow the parent widget to get the region and district values selected by the user.

Wrap Up

In this post, we discussed how to pass data from a child to its parents. This was done to make the district and region dropdown form field widget reusable.

Connect with me

Thank you for reading my post. Feel free to subscribe below to join me on the #100DaysOfCodeChallenge or connect with me on LinkedIn and Twitter. You can also buy me a book to show your support.

15