Search code examples
flutterdartdart-null-safety

Another exception was thrown: type 'Null' is not a subtype of type 'String'


getting this error showing in red screen I update my packages _TypeError Another exception was thrown: type 'Null' is not a subtype of type 'String' I tried to update the sdk and I'm not understanding where the problem is in this code. I added CircularProgressIndicator with condition statements The relevant error-causing widget was: quizpage quizpage:file:///C:/Users/flutt/Downloads/quiz/flutter-quizstar-master/lib/quizpage.dart:57:18

  class getjson extends StatefulWidget {
    
      String langname;
      getjson(this.langname);
    
      @override
      State<getjson> createState() => _getjsonState();
    }
    
    class _getjsonState extends State<getjson> {
      late String assettoload;
    
      // a function
      setasset() {
        if (widget.langname == "Science") {
          assettoload = "assets/Science.json";
        } else if (widget.langname == "Maths") {
          assettoload = "assets/Maths.json";
        } else if (widget.langname == "History") {
          assettoload = "assets/History.json";
        } 
      }
    
      @override
      Widget build(BuildContext context) {
        setasset();
        // and now we return the FutureBuilder to load and decode JSON
        return FutureBuilder(
          future:
              DefaultAssetBundle.of(context).loadString(assettoload, cache: false),
          builder: (context, snapshot) {
            if (snapshot.hasData) {
            List mydata = json.decode(snapshot.data.toString());
            if (mydata == null) {
              return Scaffold(
                body: Center(
                  child: Text(
                    "Loading",
                  ),
                ),
              );
            } else {
              return quizpage(mydata: mydata);
            }}
            return CircularProgressIndicator();
          },
        );
      }
    }
    
    class quizpage extends StatefulWidget {
      final List mydata;
    
      quizpage({required this.mydata});
      @override
      _quizpageState createState() => _quizpageState(mydata);
    }
    
    class _quizpageState extends State<quizpage> {
      final List mydata;
      _quizpageState(this.mydata);
    
      Color colortoshow = Colors.indigoAccent;
      Color right = Colors.green;
      Color wrong = Colors.red;
      int marks = 0;
      int i = 1;
      bool disableAnswer = false;
      int j = 1;
      int timer = 30;
      String showtimer = "30";
      var random_array;
    
      Map<String, Color> btncolor = {
        "a": Colors.indigoAccent,
        "b": Colors.indigoAccent,
        "c": Colors.indigoAccent,
        "d": Colors.indigoAccent,
      };
    
      bool canceltimer = false;
    
    
      genrandomarray(){
        var distinctIds = [];
        var rand = new Random();
          for (int i = 0;; ) {
          distinctIds.add(rand.nextInt(10));
            random_array = distinctIds.toSet().toList();
            if(random_array.length < 10){
              continue;
            }else{
              break;
            }
          }
          print(random_array);
      }
   
    
      @override
      void initState() {
        starttimer();
        genrandomarray();
        super.initState();
      }
    
      @override
      void setState(fn) {
        if (mounted) {
          super.setState(fn);
        }
      }
    
      void starttimer() async {
        const onesec = Duration(seconds: 1);
        Timer.periodic(onesec, (Timer t) {
          setState(() {
            if (timer < 1) {
              t.cancel();
              nextquestion();
            } else if (canceltimer == true) {
              t.cancel();
            } else {
              timer = timer - 1;
            }
            showtimer = timer.toString();
          });
        });
      }
    
      void nextquestion() {
        canceltimer = false;
        timer = 30;
        setState(() {
          if (j < 10) {
            i = random_array[j];
            j++;
          } else {
            Navigator.of(context).pushReplacement(MaterialPageRoute(
              builder: (context) => resultpage(marks: marks),
            ));
          }
          btncolor["a"] = Colors.indigoAccent;
          btncolor["b"] = Colors.indigoAccent;
          btncolor["c"] = Colors.indigoAccent;
          btncolor["d"] = Colors.indigoAccent;
          disableAnswer = false;
        });
        starttimer();
      }
    
      void checkanswer(String k) {
        
        // in the previous version this was
        // mydata[2]["1"] == mydata[1]["1"][k]
        // which i forgot to change
        // so nake sure that this is now corrected
        if (mydata[2][i.toString()] == mydata[1][i.toString()][k]) {
          // just a print sattement to check the correct working
          // debugPrint(mydata[2][i.toString()] + " is equal to " + mydata[1][i.toString()][k]);
          marks = marks + 5;
          // changing the color variable to be green
          colortoshow = right;
        } else {
          // just a print sattement to check the correct working
          // debugPrint(mydata[2]["1"] + " is equal to " + mydata[1]["1"][k]);
          colortoshow = wrong;
        }
        setState(() {
          btncolor[k] = colortoshow;
          canceltimer = true;
          disableAnswer = true;
        });
        // nextquestion();
        // changed timer duration to 1 second
        Timer(Duration(seconds: 2), nextquestion);
      }
    
      Widget choicebutton(String k) {
        return Padding(
          padding: EdgeInsets.symmetric(
            vertical: 10.0,
            horizontal: 20.0,
          ),
          child: MaterialButton(
            onPressed: () => checkanswer(k),
            child: Text(
              mydata[1][i.toString()][k],
              style: TextStyle(
                color: Colors.white,
                fontFamily: "Alike",
                fontSize: 16.0,
              ),
              maxLines: 1,
            ),
            color: btncolor[k],
            splashColor: Colors.indigo[700],
            highlightColor: Colors.indigo[700],
            minWidth: 200.0,
            height: 45.0,
            shape:
                RoundedRectangleBorder(borderRadius: BorderRadius.circular(20.0)),
          ),
        );
      }
    
      @override
      Widget build(BuildContext context) {
        SystemChrome.setPreferredOrientations(
            [DeviceOrientation.portraitDown, DeviceOrientation.portraitUp]);
        return WillPopScope(
          onWillPop: () async{
            return await showDialog(
                context: context,
                builder: (context) => AlertDialog(
                      title: Text(
                        "Welcome",
                      ),
                      content: Text("You Can't Go Back At This Stage."),
                      actions: <Widget>[
                        ElevatedButton(
                          onPressed: () {
                            Navigator.of(context).pop();
                          },
                          child: Text(
                            'Ok',
                          ),
                        )
                      ],
                    ));
          },
          child: Scaffold(
            body: Column(
              children: <Widget>[
                Expanded(
                  flex: 3,
                  child: Container(
                    padding: EdgeInsets.all(15.0),
                    alignment: Alignment.bottomLeft,
                    child: Text(
                      mydata[0][i.toString()] ,
                      style: TextStyle(
                        fontSize: 16.0,
                        fontFamily: "Quando",
                      ),
                    ),
                  ),
                ),
                Expanded(
                    flex: 6,
                    child: AbsorbPointer(
                      absorbing: disableAnswer,
                        child: Container(
                        child: Column(
                          mainAxisAlignment: MainAxisAlignment.center,
                          children: <Widget>[
                            choicebutton('a'),
                            choicebutton('b'),
                            choicebutton('c'),
                            choicebutton('d'),
                          ],
                        ),
                      ),
                    ),
                  ),
                Expanded(
                  flex: 1,
                  child: Container(
                    alignment: Alignment.topCenter,
                    child: Center(
                      child: Text(
                        showtimer,
                        style: TextStyle(
                          fontSize: 35.0,
                          fontWeight: FontWeight.w700,
                          fontFamily: 'Times New Roman',
                        ),
                      ),
                    ),
                  ),
                ),
              ],
            ),
          ),
        );
      }
    }

Solution

  • In your code some place your are show some variable in Text widget that might be null so change them to these:

    Text(
      mydata[1][i.toString()][k] ?? "",//<--- add this
      style: TextStyle(
        color: Colors.white,
        fontFamily: "Alike",
        fontSize: 16.0,
      ),
      maxLines: 1,
    )
    

    and

    Expanded(
      flex: 3,
      child: Container(
        padding: EdgeInsets.all(15.0),
        alignment: Alignment.bottomLeft,
        child: Text(
          mydata[0][i.toString()] ?? "",//<--- add this
          style: TextStyle(
            fontSize: 16.0,
            fontFamily: "Quando",
          ),
        ),
      ),
    ),