DEV Community

Cover image for How to use change the state of your material switch widget with values from cloud firestore (flutter)
debbsefe
debbsefe

Posted on

How to use change the state of your material switch widget with values from cloud firestore (flutter)

I used the Material switch widget for the first time in one of my projects and I initially found it quite tricky to use. After creating the switch widget, I wanted to change its state based on the values I received from Firestore. However, calling setState after retrieving the data did not seem to work.

Initial Code

class SwitchExample extends StatefulWidget {
  @override
  _SwitchExampleState createState() => _SwitchExampleState();
}

class _SwitchExampleState extends State<SwitchExample> {
  bool isSwitch = false;

  @override
  Widget build(BuildContext context) {
    handleSwitch(bool value) {
      setState(() {
        isSwitch = value;
      });
    }

    return StreamBuilder<QuerySnapshot>(
        stream: Firestore.instance.collection('users').snapshots(),
        builder: (context, snapshot) {
          if (snapshot.data.active == true) {
            setState(() {
              isSwitch = true;
            });
          }
          return Scaffold(
            body: Center(
              child: Switch(
                value: isSwitch,
                onChanged: (val) {
                  handleSwitch(val);
                },
                activeTrackColor: Colors.green,
                activeColor: Colors.white,
                inactiveTrackColor: Colors.grey,
              ),
            ),
          );
        });
  }
}

Thankfully, I was able to find a solution, but before I tell you what it is, here is something you should know about the switch widget.

The switch widget maintains no state of its own

The switch itself does not maintain any state. Instead, when the state of the switch changes, the widget calls the onChanged callback. Most widgets that use a switch will listen for the onChanged callback and rebuild the switch with a new value to update the visual appearance of the switch.

The lines below are the most important in the whole paragraph.

Most Widgets that use a switch will listen for the Onchanged callback and rebuild the switch with a new value to update the visual appearance of the switch

It simply means, widgets will only listen to the onchange callback and update the switch accordingly, and herein lies the problem in the initial code.
The widget cannot listen to

setState(() {
isSwitch = true;
});

because it is not being called from the onchange callback. How then do you change the state dynamically? Here’s a quick solution I was able to come up with below.

Final code

class SwitchExample extends StatefulWidget {
  @override
  _SwitchExampleState createState() => _SwitchExampleState();
}

class _SwitchExampleState extends State<SwitchExample> {
  bool isSwitch = false;
  bool dynamicSwitch;

  @override
  Widget build(BuildContext context) {
    handleSwitch(bool value) {
      setState(() {
        isSwitch = value;
        dynamicSwitch = value;
      });
    }

    return StreamBuilder<QuerySnapshot>(
        stream: Firestore.instance.collection('users').snapshots(),
        builder: (context, snapshot) {
          dynamicSwitch = snapshot.data.active;

          return Scaffold(
            body: Center(
              child: Switch(
                value: dynamicSwitch != true ? isSwitch : dynamicSwitch,
                onChanged: (val) {
                  handleSwitch(val);
                },
                activeTrackColor: Colors.green,
                activeColor: Colors.white,
                inactiveTrackColor: Colors.grey,
              ),
            ),
          );
        });
    }
  }
}

So now depending on the value you have in your collection, your switch will change accordingly.

To test out this code, you can create a collection called users on firebase with a document. In the document, create a field (‘active) and set its value to true or false.

I hope you enjoyed this article and thanks for reading till the end.

Top comments (1)

Collapse
 
imaduddinkhan profile image
Imad Ud Din Khan

.active is not working