Home > Software engineering >  Conditional widget is not working or changing after data load in Flutter
Conditional widget is not working or changing after data load in Flutter

Time:04-16

I am just writing a simple application using flutter. I came across a situation where I need to display widgets conditionally. I am fetching data using app script API from Google Sheets. I want to show the "Loading..." text during loading and want to hide it after completing the request.

The following code works as expected if I run it within/using Android Studio. But If I build the APK and install it on my device, only "Loading..." text is showing on the screen, although the data is loaded and stored in listResponse.

class HomePage extends StatefulWidget {
  const HomePage({Key? key, required this.title, required this.baseUrl}) : super(key: key);
  final String title;
  final String baseUrl;

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  late List listResponse = [];

  Future categories() async {
    var url = widget.baseUrl   'categories';
    http.Response response = await http.get(Uri.parse(url));
    if(response.statusCode == 200){
      setState(() {
        listResponse = json.decode(response.body);
        print(listResponse.toString());
      });
    }
  }

  @override
  void initState(){
    categories();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: TopBar(title: widget.title),
      body: listResponse.isEmpty ? Center(child: Text('Loading...')) :  Center(child: Text(listResponse.toString()))
    );
  }
}

I have searched for the solution and found some examples on stackoverflow. What could be the issue as the app is running as expected in development. I appreciate the help.

CodePudding user response:

You can use condition value to show loading and result, Take bool isSuccess = false and in your statusCode==200 setState make it isSuccess = true

class _HomePageState extends State<HomePage> {
  late List listResponse = [];
  bool isSuccess = false;

  Future categories() async {
    var url = widget.baseUrl   'categories';
    http.Response response = await http.get(Uri.parse(url));
    if(response.statusCode == 200){
      setState(() {
        listResponse = json.decode(response.body);
        isSuccess = true;
        print(listResponse.toString());

      });
    }
  }

  @override
  void initState(){
    categories();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: TopBar(title: widget.title),
      body: isSuccess  ? Center(child: Text('Loading...')) :  Center(child: Text(listResponse.toString()))
    );
  }

It will work fine when data is fetched. Or you can also use FutureBiulder

  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
        future: categories(),
        builder: (context, snapshot) {
          if (snapshot.hasError) {
            return Text(
              'There was an error :(',
              style: Theme.of(context).textTheme.headline,
            );
          } else if (snapshot.hasData) {
            var count = json.decode(snapshot.data).length;
            return Center(child: Text(listResponse.toString()));
          } else {
            return Center(child: Text('Loading...')) 
          }
        });
  }
  • Related