title: Flutter order of execution: build and initState
body: <p>I'm trying to create a preferences menu where I have three settings (e. g. 'notifications') stored with Shared Preferences. They are applied to SwitchListTiles.</p>
  
  <p>Everytime my settings tab is selected there is an error (I/flutter (22754): Another exception was thrown: 'package:flutter/src/material/switch_list_tile.dart': Failed assertion: line 84 pos 15: 'value != null': is not true.) appearing just a millisecond. After that the correct settings are displayed. This happens when I don't add a default value to the variables initialized in 'ProfileState'. If they have a default value the error disappears but the switches are 'flickering' at tab selection from the default value to the correct value in Shared Preferences. </p>
  
  <p>My assumption is that my loadSettings function is executed after the build method.</p>
  
  <p>How can I solve that? Any help is appreciated.</p>
  
  <pre><code>import 'package:flutter/material.dart';
  import 'package:shared_preferences/shared_preferences.dart';
  
  class Profile extends StatefulWidget {
    @override
    ProfileState createState() {
      return new ProfileState();
    }
  }
  
  class ProfileState extends State&lt;Profile&gt; {
    bool notifications;
    bool trackHistory;
    bool instantOrders;
  
    @override
    void initState() {
      super.initState();
      loadSettings();
    }
  
    //load settings
    loadSettings() async {
      SharedPreferences prefs = await SharedPreferences.getInstance();
      setState(() {
        notifications = (prefs.getBool('notifications') ?? true);
        trackHistory = (prefs.getBool('trackHistory') ?? true);
        instantOrders = (prefs.getBool('instantOrders') ?? false);
      });
    }
  
    //set settings
    setSettings() async {
      SharedPreferences prefs = await SharedPreferences.getInstance();
      prefs.setBool('notifications', notifications);
      prefs.setBool('trackHistory', trackHistory);
      prefs.setBool('instantOrders', instantOrders);
    }
  
    @override
    Widget build(BuildContext context) {
      return new ListView(
        children: &lt;Widget&gt;[
          new Row(
            children: &lt;Widget&gt;[
              new Container(
                padding: new EdgeInsets.fromLTRB(20.0, 20.0, 0.0, 8.0),
                child: new Text("General", style: new TextStyle(color: Colors.black54)),
              )
            ],
          ),
          new SwitchListTile(
            title: const Text('Receive Notifications'),
            activeColor: Colors.brown,
            value: notifications,
            onChanged: (bool value) {
              setState(() {
                notifications = value;
                setSettings();
              });
            },
            secondary: const Icon(Icons.notifications, color: Colors.brown),
          ),
          new SwitchListTile(
            title: const Text('Track History of Orders'),
            activeColor: Colors.brown,
            value: trackHistory,
            onChanged: (bool value) {
              setState((){
                trackHistory = value;
                setSettings();
              });
            },
            secondary: const Icon(Icons.history, color: Colors.brown,),
          ),
          new SwitchListTile(
            title: const Text('Force instant Orders'),
            activeColor: Colors.brown,
            value: instantOrders,
            onChanged: (bool value) {
              setState((){
                instantOrders = value;
                setSettings();
              });
            },
            secondary: const Icon(Icons.fast_forward, color: Colors.brown),
          ),
          new Divider(
            height: 10.0,
            ),
          new Container(
            padding: EdgeInsets.all(32.0),
            child: new Center(
              child: new Column(
                children: &lt;Widget&gt;[
                  new TextField(
                  )
                ],
              ),
            ),
          ),
          new Divider(
            height: 10.0,
          ),
          new Row(
            children: &lt;Widget&gt;[
              new Container(
                padding: new EdgeInsets.fromLTRB(20.0, 20.0, 0.0, 20.0),
                child: new Text("License Information", style: new TextStyle(color: Colors.black54)),
              )
            ],
          ),
          new Container(
            padding: new EdgeInsets.fromLTRB(20.0, 0.0, 20.0, 20.0) ,
            child: new RichText(
              text: new TextSpan(
                text: "With confirming our terms and conditions you accept full usage of your personal data. Yikes!",
                style: new TextStyle(color: Colors.black)
              )
            )
          )
        ]
      );
    }
  }
  </code></pre>
  
  <p><strong>EDIT</strong></p>
  
  <p>I tried to solve it with the recommended FutureBuilder from Darek's solution. The initial error is solved now but now I face another inconvenience. The tab builds itself completely everytime a switch is tapped which is clearly noticable. Furthermore the switches don't run smoothly anymore. On startup of the app you can also see the waiting message shortly which isn't that pretty.</p>
  
  <p>Here is the new class in the code:</p>
  
  <pre><code>class ProfileState extends State&lt;Profile&gt; {
    bool notifications;
    bool trackHistory;
    bool instantOrders;
    SharedPreferences prefs;
  
    @override
    void initState() {
  
      super.initState();
      loadSettings();
    }
  
    //load settings
    Future&lt;String&gt; loadSettings() async {
      prefs = await SharedPreferences.getInstance();
      notifications= (prefs.getBool('notifications') ?? true);
      trackHistory = (prefs.getBool('trackHistory') ?? true);
      instantOrders= (prefs.getBool('instantOrders') ?? true);
    }
  
    //set settings
    setSettings() async {
      prefs.setBool('notifications', notifications);
      prefs.setBool('trackHistory', trackHistory);
      prefs.setBool('instantOrders', instantOrders);
    }
  
    @override
    Widget build(BuildContext context) {
      var profileBuilder = new FutureBuilder(
        future: loadSettings(), // a Future&lt;String&gt; or null
        builder: (BuildContext context, AsyncSnapshot&lt;String&gt; snapshot) {
          switch (snapshot.connectionState) {
            case ConnectionState.none:
              return new Text('No preferences');
            case ConnectionState.waiting:
              return new Text('Loading preferences');
            case ConnectionState.done:
              if (snapshot.hasError)
                return new Text('Error: ');
              else
                return new Column(
                    children: &lt;Widget&gt;[
                      new Row(
                        children: &lt;Widget&gt;[
                          new Container(
                            padding: new EdgeInsets.fromLTRB(20.0, 20.0, 0.0, 8.0),
                            child: new Text("General", style: new TextStyle(color: Colors.black54)),
                          )
                        ],
                      ),
                      new SwitchListTile(
                        title: const Text('Receive Notifications'),
                        activeColor: Colors.brown,
                        value: notifications,
                        onChanged: (bool value) {
                          setState(() {
                            notifications = value;
                            setSettings();
                          });
                        },
                        secondary: const Icon(Icons.notifications, color: Colors.brown),
                      ),
                      new SwitchListTile(
                        title: const Text('Track History of Orders'),
                        activeColor: Colors.brown,
                        value: trackHistory,
                        onChanged: (bool value) {
                          setState((){
                            trackHistory = value;
                            setSettings();
                          });
                        },
                        secondary: const Icon(Icons.history, color: Colors.brown,),
                      ),
                      new SwitchListTile(
                        title: const Text('Force instant Orders'),
                        activeColor: Colors.brown,
                        value: instantOrders,
                        onChanged: (bool value) {
                          setState((){
                            instantOrders = value;
                            setSettings();
                          });
                        },
                        secondary: const Icon(Icons.fast_forward, color: Colors.brown),
                      ),
                      new Divider(
                        height: 10.0,
                      ),
                      new Row(
                        children: &lt;Widget&gt;[
                          new Container(
                            padding: new EdgeInsets.fromLTRB(20.0, 20.0, 0.0, 20.0),
                            child: new Text("License Information", style: new TextStyle(color: Colors.black54)),
                          )
                        ],
                      ),
                      new Container(
                          padding: new EdgeInsets.fromLTRB(20.0, 0.0, 20.0, 20.0) ,
                          child: new RichText(
                              text: new TextSpan(
                                  text: "With confirming our terms and conditions you accept full usage of your personal data. Yikes!",
                                  style: new TextStyle(color: Colors.black)
                              )
                          )
                      )
                    ]
                );
          }
        },
      );
      return new Scaffold(
        body: profileBuilder,
      );
  
  
    }
  }
  </code></pre>