fluttershowdialog

flutter showdialog setState() or markNeedsBuild() called during build


I have a streambuilder which reads a firestore database and then react according to that. it is currenlty listing some info from my database however i want to add a popup screen for a specific value occurs in the database and when i added a showdialog function it started to give me

    ════════ Exception caught by widgets library ═══════════════════════════════════════════════════════
setState() or markNeedsBuild() called during build.

error. How can i fix this? My code is below. Thanks in advance.

//This is the function causing errors.      
_showMaterialDialog (String type) {
        if(type=="win"){
          gameResult = "You Win, Gratz!";
        }else if(type=="lose"){
          gameResult = "You Lose :(";
        }
        print("buraya girdi");
        print(gameResult);
        showDialog(
            context: context,
            builder: (_) => AlertDialog(
              title: Text("Result"),
              content: Text(gameResult),
              actions: <Widget>[
                FlatButton(
                  child: Text('Close'),
                  onPressed: () {
                    //Navigator.of(context).pop();
                    Navigator.pushNamed(context, HomeScreen.id);
                  },
                )
              ],
            ));
      }
    
      @override
      Widget build(BuildContext context) {
        if(_error) {
          return Text('error-game', textDirection: TextDirection.ltr);
        }
    
        // Show a loader until FlutterFire is initialized
        if (!_initialized) {
          return Text('Loading', textDirection: TextDirection.ltr);
        }
        return StreamBuilder<DocumentSnapshot>(
          stream: userSnapshot,
          builder: (BuildContext context, AsyncSnapshot<DocumentSnapshot> snapshot) {
            if (snapshot.hasError) {
              return Text('Something went wrong');
            }
    
            if (snapshot.connectionState == ConnectionState.waiting) {
              return Text("Loading");
            }
            if(snapshot.hasData){
              Map<String, dynamic> userDocument  = snapshot.data.data();
              print(collectionPath);
              print(docPath);
              print(snapshot.data);
              print(userDocument);
              gameResult = userDocument['status'];

//this is place function called

              if(gameResult =="win" || gameResult =="lose"){
                return _showMaterialDialog(gameResult);
              }


              kullanicisayilari = userDocument['atilansayi'];
              List<dynamic> kullanicisayilariDuz = [];
              List<dynamic> rakipsayilariDuz = [];
              List<dynamic> sonuclarDuz = [];
              for (var numbers in kullanicisayilari){
                var splittedNumber = numbers.split('|');
                kullanicisayilariDuz.add(splittedNumber[0]);
              }
              rakipsayilari = userDocument['rakipsallama'];
              sonuc = userDocument['sonuc'];
              for (var sonuclar in sonuc){
                var splittedSonuc = sonuclar.split('|');
                sonuclarDuz.add(splittedSonuc[0]);
              }
              for (var rakipsayi in rakipsayilari){
                var splittedRakipSayi = rakipsayi.split('|');
                rakipsayilariDuz.add(splittedRakipSayi[0]);
              }
              print(myNumbers.decimals);
              return MaterialApp(
                home:Scaffold(
                  appBar: AppBar(
                    backgroundColor: Colors.amberAccent,
                    title: Text('Sayı Avı Oyun Ekranı'),
                  ),
                  body:Column(
                    children: <Widget>[
                      Expanded(
                        flex: 80,
                        child: Row(
                          children: <Widget>[
                            Expanded(
                              flex: 40,
                              child: Column(
                                children: <Widget>[
                                  for(var numbers in kullanicisayilariDuz)Text(numbers),
                                  ]
                              ),
                            ),
                            Expanded(
                              flex: 10,
                              child: Column(
                                  children: <Widget>[
                                    for(var numbers in sonuclarDuz)Text(numbers),
                                  ]
                              ),
                            ),
                            Expanded(
                              flex: 50,
                              child: Column(
                                children: <Widget>[
                                  for(var numbers in rakipsayilariDuz)Text(numbers),
                                ]
                              ),
                            ),
                          ],
                        ),
                      ),
                      Expanded(
                        flex:10,
                        child: Row(
                          mainAxisAlignment: MainAxisAlignment.center,
                          children: <Widget>[
                            showDeleteNumbers(1,'numberimage1'),
                            showDeleteNumbers(2,'numberimage2'),
                            showDeleteNumbers(3,'numberimage3'),
                            showDeleteNumbers(4,'numberimage4'),
                            Expanded(
                              child:FlatButton(
                                onPressed: (){
                                  sendnumber();
                                },
                                child: Image.asset('images/send.png'),
                              ),
                            ),
                          ],
                        ),
                      ),
                      Expanded(
                        flex: 10,
                        child: Row(
                          children: <Widget>[
                            attachNumber('1','one.png'),
                            attachNumber('2','two.png'),
                            attachNumber('3','three.png'),
                            attachNumber('4','four.png'),
                            attachNumber('5','five.png'),
                            attachNumber('6','six.png'),
                            attachNumber('7','seven.png'),
                            attachNumber('8','eight.png'),
                            attachNumber('9','nine.png'),
                            attachNumber('0','zero.png'),
                          ],
                        ),
                      ),
                    ],
                  ),
                ),
              );
            }
          },
        );
      }

    }

Solution

  • After a bit research i understood that the problem is occuring becuase functions widget building causing problems as there is an already a build event occuring so i made the function asycn and it is working now.

    Here is the code:

      _showMaterialDialog(String type) async{
        if(type=="win"){
          gameResult = "You Win, Gratz!";
        }else if(type=="lose"){
          gameResult = "You Lose :(";
        }
        print("buraya girdi");
        print(gameResult);
        await Future.delayed(Duration(milliseconds: 50));
        showDialog (
            context: context,
            builder: (_) => AlertDialog(
              title: Text("Result"),
              content: Text(gameResult),
              actions: <Widget>[
                FlatButton(
                  child: Text('Close'),
                  onPressed: () {
                      Navigator.pushNamed(context, HomeScreen.id);
                  },
                )
              ],
            ));
      }