Returning scaffold conditionally throws error

Issue

I am trying to load a new welcome scaffold if the user is logged in , which is working fine , but before building welcome scaffold error screen pops up for a couple of seconds and then it show up.I am new to this please correct me if i am wrong somewhere.Thanks

This is the error i get before the welcome screen loads up.

WelcomPage :

    class WelcomePage extends StatefulWidget {
    @override
    _WelcomePageState createState() => new _WelcomePageState();
  }      

  enum FormType { admin, member }      

  class _WelcomePageState extends State<WelcomePage> {
    var role;
    SharedPrefClass pref;      

    FormType _formType;
    WidgetsElements widDemo = new WidgetsElements();      

    void moveToadmin() {
      setState(() {
        _formType = FormType.admin;
      });
    }      

    void moveTomember() {
      setState(() {
        _formType = FormType.member;
      });
    }      

    void setFormType() {
      pref = new SharedPrefClass();
      pref.getRoleId().then((value) {
        setState(() {
          this.role = value;
          if (role == 2)
            return moveToadmin();
          else
            return moveTomember();
        });
      });
    }      

    @override
    void initState() {
      // TODO: implement initState
      super.initState();
      setFormType();
    }      

    List<Widget> submitWidgets() {
      switch (_formType) {
        case FormType.admin:
          return [
            MaterialButton(
              minWidth: 200.0,
              height: 42.0,
              onPressed: () {},
              color: Colors.white,
              child: Text('CheckIn/Out', style: TextStyle(color: Colors.grey)),
            ),
            MaterialButton(
              minWidth: 500.0,
              height: 42.0,
              onPressed: () {
                // _login();
              },
              color: Colors.white,
              child: Text('Register POS', style: TextStyle(color: Colors.grey)),
            ),
            MaterialButton(
              minWidth: 200.0,
              height: 42.0,
              onPressed: () {
                // _login();
              },
              color: Colors.white,
              child:
                  Text('Order Placement', style: TextStyle(color: Colors.grey)),
            ),
          ];
        case FormType.member:
          return [
            MaterialButton(
              minWidth: 200.0,
              height: 42.0,
              onPressed: () {
                // _login();
              },
              color: Colors.white,
              child:
                  Text('Register Customer', style: TextStyle(color: Colors.grey)),
            ),
            MaterialButton(
              minWidth: 200.0,
              height: 42.0,
              onPressed: () {
                // _login();
              },
              color: Colors.white,
              child: Text('Customer Order', style: TextStyle(color: Colors.grey)),
            ),
            MaterialButton(
              minWidth: 200.0,
              height: 42.0,
              onPressed: () {
                // _login();
              },
              color: Colors.white,
              child: Text('Re-Order Stock', style: TextStyle(color: Colors.grey)),
            ),
          ];
      }
      return null;
    }      

    checkRole() {
      pref.clearAll().then((_) {
        setState(() {
          this.role = null;
        });
      });
      return role;
    }      

    @override
    Widget build(BuildContext context) {
      return new Scaffold(
        appBar: new AppBar(
          title: new Text("Welcome Page"),
          backgroundColor: Colors.redAccent,
          actions: <Widget>[
            IconButton(
              icon: Icon(Icons.close),
              onPressed: () {
                print('clicked');
                pref.clearAll();
                print(role);
                if (role == null) Navigator.pushReplacementNamed(context, '/');
              },
            ),
          ],
        ),
        body: new Center(
          child: new Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              new Container(
                  padding: const EdgeInsets.all(16.0),
                  child: new Form(
                      child: new Column(
                    crossAxisAlignment: CrossAxisAlignment.stretch,
                    children: submitWidgets(),
                  ))),
            ],
          ),
        ),
      );
    }
  }

  class LoginPage extends StatefulWidget {
   @override
   _LoginPageState createState() => new _LoginPageState();
 }

 class _LoginPageState extends State<LoginPage> {
   String _appVersion;
   String _deviceId;
   String _platforrm;
   var role;
   bool isLoggedIn = false;

   SharedPrefClass spref = new SharedPrefClass();

   DeveloperManager dmanager = new DeveloperManager();
   String savedeviceid() {
     dmanager.initDeviceId().then((value) {
       setState(() {
         _deviceId = value;
       });
     });
     return _deviceId;
   }

   String saveVersion() {
     dmanager.initPackageInfo().then((value) {
       setState(() {
         _appVersion = value;
       });
     });
     return _appVersion;
   }

   String savePlatform() {
     dmanager.platforms().then((value) {
       setState(() {
         _platforrm = value;
       });
     });
     return _platforrm;
   }

   final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();

   RestData restData = new RestData();

   @override
   void initState() {
     // TODO: implement initState
     super.initState();
     savedeviceid();
     saveVersion();
     savePlatform();

     spref.getRoleId().then((updateName) {
       setState(() {
         this.role = updateName;
         if (role != null)
           isLoggedIn = true;
         else
           isLoggedIn = false;

         //  print(role);
       });
     });
   }

   @override
   Widget build(BuildContext context) {

     return !isLoggedIn
         ? Scaffold(
             key: _scaffoldKey,
             appBar: new AppBar(
               title: new Text("Login"),
             ),
             body: Center(
               child: ListView(
                 shrinkWrap: true,
                 padding: EdgeInsets.only(left: 24.0, right: 24.0),
                 children: <Widget>[
                   logo,
                   SizedBox(height: 48.0),
                   email,
                   SizedBox(height: 8.0),
                   password,
                   SizedBox(height: 24.0),
                   loginButton,
                   SizedBox(height: 24.0),
                   // loginButton2,
                 ],
               ),
             ),
           )
         : new WelcomePage();
   }
 }

Solution

The issue might be due to the value of _formType being null here

List<Widget> submitWidgets() {
          switch (_formType) {

You get this value using:

pref.getRoleId().then((value)...

You need to wait for this async process to complete before using _formType. However, you are using the variable _formType inside submitWidgets without any null checks or check for async process completion.

One solution would be to add a value waiting to enum FormType { waiting, admin, member }.

Then, initialize _formType = FormType.waiting (so that waiting is the default value)

Finally handle:

List<Widget> submitWidgets() {
      switch (_formType) {
        case FormType.waiting:
        ...

You may return a List<Widget> with a loading/please wait message like Text("Loading ...") here

Answered By – Kartik

Answer Checked By – David Goodson (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published.