Is there any way to display a component only if there is data in the json file to populate it?

Asked

Viewed 41 times

1

I’m doing a quiz app and it turns out that some questions have 5 and others have only 4 alternatives. In the tutorial I followed it creates 4 choicebutton. I, who am very innocent, added a fifth, which is empty when there is no fifth alternative. I still want to learn how to make a more dynamic screen, but for now I just wanted to hide the fifth option if there is no data for it.

Don’t mind the mess of the code, I’ll still fix it

import 'dart:async';
import 'package:firebase_admob/firebase_admob.dart';
import 'package:flutter/material.dart';
import 'dart:convert';
import 'package:flutter/services.dart';
import 'package:queazybymtvr/resultpage.dart';
import 'ad_manager.dart';
import 'home.dart';
import 'package:shared_preferences/shared_preferences.dart';

class getjson extends StatelessWidget {

  String mat;
  getjson(this.mat);
  String assettoload;

  setasset() {
    if (mat == "lp") {
      assettoload = "assets/lp.json";
      debugPrint(assettoload);
    }else{
      debugPrint("não clicou em língua portuguesa");
    }
  }

  @override
  Widget build(BuildContext context) {
    setasset();
    return FutureBuilder(
      future:
      DefaultAssetBundle.of(context).loadString(assettoload, cache: false),
      builder: (context, snapshot){
        var mydata = json.decode(snapshot.data.toString());
        if(mydata == null){
          return Scaffold(
            body: Center(
              child: Text(
                "Loading",
              ),
            ),
          );
        }else{
          return quizpage(mydata : mydata);
        }
      },
    );
  }
}

class quizpage extends StatefulWidget {



  var mydata;

  quizpage({Key key, @required this.mydata}) : super(key : key);

  @override
  _quizpageState createState() => _quizpageState(mydata);
}

class _quizpageState extends State<quizpage> {

  bool _isRewardedAdReady;

  void _loadRewardedAd() {
    RewardedVideoAd.instance.load(
      targetingInfo: MobileAdTargetingInfo(),
      adUnitId: AdManager.rewardedAdUnitId,
    );
  }

  void _onRewardedAdEvent(RewardedVideoAdEvent event,
      {String rewardType, int rewardAmount}) {
    switch (event) {
      case RewardedVideoAdEvent.loaded:
        setState(() {
          _isRewardedAdReady = true;
        });
        break;
      case RewardedVideoAdEvent.closed:
        setState(() {
          _isRewardedAdReady = false;
        });
        _loadRewardedAd();
        break;
      case RewardedVideoAdEvent.failedToLoad:
        setState(() {
          _isRewardedAdReady = false;
        });
        print('Failed to load a rewarded ad');
        break;
      case RewardedVideoAdEvent.rewarded:
        setState(() {
          //TODO: passar para a próxima questão
          i++;
          ultimaQuestao(i);
        });

        break;
      default:
      // do nothing
    }
  }

  SharedPreferences _preferences;

  String _ultimaQuestao = 'ultimaQuestao';
  String _marks = 'marks';
  
  Future ultimaQuestao(int q) async {
    final _preferences = await SharedPreferences.getInstance();
    setState(() {
      _preferences.setInt(_ultimaQuestao, q);
      _preferences.setInt(_marks, marks);
    });
  }

  Future setMarks(int marks) async {
    final _preferences = await SharedPreferences.getInstance();
    setState(() {
      _preferences.setInt(_marks, marks);
    });
  }

  getUltimaQuestao() async {
    SharedPreferences _preferences = await SharedPreferences.getInstance();
    setState(() {
      if(_preferences.getInt(_ultimaQuestao) != null){
        i = _preferences.getInt(_ultimaQuestao);
        debugPrint("i.toString() = " + i.toString());
      }else{
        i =  1;
      }
    });


  }



  InterstitialAd _interstitialAd;
  BannerAd _bannerAd;
  bool _isInterstitialAdReady;

  Future<void> _initAdMob() {

    return FirebaseAdMob.instance.initialize(appId: AdManager.appId);
  }

  void _loadBannerAd() {
    _bannerAd
      ..load()
      ..show(
        anchorOffset: 0.0,
        horizontalCenterOffset: 0.0,
        anchorType: AnchorType.bottom
      );
  }

  void _loadInterstitialAd() {
    _interstitialAd.load();
  }

  @override
  void dispose() {

    RewardedVideoAd.instance.listener = null;

    _bannerAd?.dispose();

    _interstitialAd?.dispose();

    super.dispose();
  }

  var mydata;

  _quizpageState(this.mydata);

  Color colortoshow = Colors.indigoAccent;
  Color right = Colors.green;
  Color wrong = Colors.red;
  int marks = 0;
  Future<int> uq;
  int i = 1;
  //int timer = 30;
  //String showtimer = "30";
  //int interstitial_timer = 10;

  Map<String, Color> btncolor = {
    "a" : Colors.indigoAccent,
    "b" : Colors.indigoAccent,
    "c" : Colors.indigoAccent,
    "d" : Colors.indigoAccent,
    "e" : Colors.indigoAccent
  };

  bool canceltimer = false;

  @override
  void initState(){


    _bannerAd = BannerAd(
      adUnitId: AdManager.bannerAdUnitId,
      size: AdSize.banner,
    );


    _loadBannerAd();


    _isInterstitialAdReady = false;



    _interstitialAd = InterstitialAd(
      adUnitId: AdManager.interstitialAdUnitId,
      listener: _onInterstitialAdEvent,
    );

    //show_interstitial_ad();

    getUltimaQuestao();


    _isRewardedAdReady = false;

    RewardedVideoAd.instance.listener = _onRewardedAdEvent;

    _loadRewardedAd();

    //starttimer();




    super.initState();
  }





  void _onInterstitialAdEvent(MobileAdEvent event) {
    switch (event) {
      case MobileAdEvent.loaded:
        _isInterstitialAdReady = true;
        break;
      case MobileAdEvent.failedToLoad:
        _isInterstitialAdReady = false;
        print('Failed to load an interstitial ad');
        break;
      case MobileAdEvent.closed:

        break;
      default:
      // do nothing
    }
  }




  /*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 show_interstitial_ad(){
    InterstitialAd interstitialAd = new InterstitialAd(
        adUnitId: InterstitialAd.testAdUnitId,
        listener: (MobileAdEvent e) {
          print("Mobile ad event => $e");
        });
    interstitialAd.load().then((val) {
      interstitialAd.show();
    });
  }

  void nextquestion(){

    _loadInterstitialAd();
    //canceltimer = false;
    //timer = 30;
    setState(() {
      if(i < 10){
        if(i % 5 == 0) {
          showDialog(
              context: context,
              builder: (context) =>
                  AlertDialog(
                    title: Text("Queazer by MTVR"),
                    content: Text(
                        "Assita uma propaganda para acessar mais 10 questões."),
                    actions: <Widget>[
                      FlatButton(
                        child: Text("Cancelar"),
                        onPressed: () {
                          Navigator.pop(context);
                        },
                      ),
                      FlatButton(
                        child: Text("OK"),
                        onPressed: () {
                          Navigator.pop(context);

                          RewardedVideoAd.instance.show();

                        },
                      )
                    ],
                  )
          );
        }else{
          i++;
          ultimaQuestao(i);

        }
        //show_interstitial_ad();
      }else{
        ultimaQuestao(1);
        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;
      btncolor["e"] = Colors.indigoAccent;

    });
    //starttimer();


  }

  void checkanswer(String k){
    //if(mydata[2][i.toString()] == mydata[1][i.toString()][k]){
    if(k == mydata[2][i.toString()]){
      //marks = marks +5;
      colortoshow= right;
      //setMarks(marks);
    }else{
      colortoshow = wrong;
    }
    setState(() {
      btncolor[k] = colortoshow;
      canceltimer = true;
    });


    Timer(Duration(seconds: 1), nextquestion);
  }

  Widget choicebutton(String k){
    return Padding(
      padding: EdgeInsets.zero,
      child: MaterialButton(
        onPressed: (){
          checkanswer(k);
          debugPrint("k = " + k + " e i.toString() = " + i.toString());
          debugPrint("mydata[2][i.toString()] = " + mydata[2][i.toString()] + ", mydata[1][i.toString()][k] = " + mydata[1][i.toString()][k]);
        },
        child: Text(
          mydata[1][i.toString()][k],

          style: TextStyle(
            fontSize: 16.0,
            fontFamily: "Alike-Regular",
            color: Colors.white
          ),
          //maxLines: 1,
        ),
        color: btncolor[k],
        splashColor: Colors.indigo[700],
        highlightColor: Colors.indigo[700],
        minWidth: 200.0,
        height: 45.0,
        shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(5.0))
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    SystemChrome.setPreferredOrientations([
      DeviceOrientation.portraitDown,
      DeviceOrientation.portraitUp
    ]);
    return WillPopScope(
      onWillPop: (){
        return showDialog(
          context: context,
          builder: (context) => AlertDialog(
            title: Text(
              "Queazy by MTVR",
            ),
            content: Text(
              "Deseja realmente sair?"
            ),
            actions: <Widget>[
              FlatButton(
                onPressed: (){
                  Navigator.of(context).pop();
                },
                child: Text("Cancelar"),
              ),
              FlatButton(
                onPressed: (){
                  Navigator.of(context).pushReplacement(MaterialPageRoute(
                      builder: (context) => homepage()));
                  //TODO: sair e destruir a tela

                },
                child: Text("Sair"),
              )
            ],
          )
        );
        //TODO: destruir a página

      },
        child: Scaffold(
          appBar: AppBar(
            title: Text("Língua Portuguesa"),
            centerTitle: true,
          ),
        body: ListView(
          children: <Widget>[
            Expanded(
              flex: 2,
              child: Container(
                padding: EdgeInsets.all(15.0),
                alignment: Alignment.bottomLeft,

                child: Text(
                  i.toString() + " - " + mydata[0][i.toString()],
                  style: TextStyle(
                      fontSize: 16.0,
                      fontFamily: "Quando"
                  ),
                ),
              ),
            ),
            Expanded(
              flex: 7,
              child: Container(
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: <Widget>[
                    choicebutton('a'),
                    choicebutton('b'),
                    choicebutton('c'),
                    choicebutton('d'),
                    choicebutton('e'),
                  ],
                ),
              ),
            ),
            Expanded(
              flex: 1,
              child: Padding(
                padding: EdgeInsets.only(bottom: 60.0),
                child: Container(
                  alignment: Alignment.topCenter,
                  child: Center(
                    child: Container(
                      ),
                    ),
                  ),
                ),
              ),
          ],
        ),
      )
    );
  }
}

1 answer

1


Your code can be improved and refactored in some points, however, I attend to the focus of the question:

You can use the ternary operator which Dart makes available. If the check is false, put to receive null value. As follows:

[...]
children: <Widget>[
                    choicebutton('a'),
                    choicebutton('b'),
                    choicebutton('c'),
                    choicebutton('d'),
                    TemDados() ? choicebutton('e') : null,
                  ],
[...]

By your code, you can’t know exactly what the variable format is like mydata, but I believe your verification would have to be something like:

mydata[1][i.toString()].containsKey("e")

containsKey() is a method that returns true if the key is present in the dictionary.

However, by way of curiosity, after Dart 2.3, you too can wear a if inside a collection. I believe it to be more readable, and more elegant. In your case it would be:

children: <Widget>[
                    choicebutton('a'),
                    choicebutton('b'),
                    choicebutton('c'),
                    choicebutton('d'),
                    if (TemDados()) choicebutton('e'),
                  ],
[...]
  • Wow, man! Thank you so much. I’ll work on it after I make the basics work. By the way, this mydata recovers data from a json file that is what I learned in the tutorial but in the next version of the app I intend to use firebase pq in the case of the app (contest questions) compensates.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.