0

I'm trying to fetch data from an API to display it in a gridview but asyncloader is fetching and displaying extra fields when they don't exist. Why is this happening? The issue is only when I log out from the app and login again. If I don't log out the issue solves itself and the gridview only displays the amount of data fetched from the API.

This is my AsyncLoader:

var offerAsync = AsyncLoader(
  initState: () async => await fetchOffers(),
  renderLoad: () => Center(child: CircularProgressIndicator()),
  renderSuccess: ({data}) => GridView.builder(
      gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
          childAspectRatio:
              (SizeConfig.blockSizeHorizontal / SizeConfig.blockSizeVertical) *
                  1.4,
          mainAxisSpacing: SizeConfig.blockSizeVertical * 1,
          crossAxisSpacing: 2.0,
          crossAxisCount: 3),
      itemCount: dashGridImages.length,
      itemBuilder: (context, index) {
        return Card(
          elevation: 4,
          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.all(Radius.circular(10.0)),
          ),
          color: dashGridColors[index],
          child: Column(
            children: [
              ClipRRect(
                borderRadius: BorderRadius.circular(10.0),
                child: Image.network(
                  dashGridImages[index],
                  fit: BoxFit.cover,
                  height: SizeConfig.blockSizeVertical * 12,
                ),
              ),
              SizedBox(height: SizeConfig.blockSizeVertical * 1),
              Text(
                dashGridMainText[index],
                style: TextStyle(
                    fontSize: smallTextSize,
                    color: index != 4 ? Colors.white : Colors.grey[700],
                    wordSpacing: -0.7),
                textAlign: TextAlign.center,
              ),
              SizedBox(height: SizeConfig.blockSizeVertical * 1),
              Text(
                dashGridExpireText[index],
                style: TextStyle(
                  fontSize: ultraSmallTextSize,
                  color: index != 4 ? Colors.black : Colors.grey[700],
                ),
                textAlign: TextAlign.center,
              ),
            ],
          ),
        );
      }),
);

This is the method that fetches data:

Future fetchOffers() async {
  List<Color> tempColor;
  try {
    offerResponse = await http.get(offers);
    if (offerResponse.statusCode == 200) {
      offerResponse = jsonDecode(offerResponse.body);
      offerData = offerResponse['data'];
      List<dynamic> data = offerData as List;
      data.forEach((item) => dashGridMainText.add(item['title']));
      data.forEach((item) => dashGridImages.add(item['offer_image']));
      data.forEach((item) => dashGridExpireText.add(item['offer_expiry_date']));
      print("Main Text Count: ${dashGridMainText.length}");
      print("Image Count: ${dashGridImages.length}");
      print("Expire Text Count: ${dashGridExpireText.length}");
            return data;
    }
  } catch (e) {
    print(e);
  }
}

My implementation using ternary operator:

bool isDataLoaded = false;

  Future fetchOffers() async {
    // List<Color> tempColor;
    try {
      offerResponse = await http.get(offers);
      if (offerResponse.statusCode == 200) {
        offerResponse = jsonDecode(offerResponse.body);
        offerData = offerResponse['data'];
          List<dynamic> data = offerData as List;
          data.forEach((item) => dashGridMainText.add(item['title']));
          data.forEach((item) => dashGridImages.add(item['offer_image']));
          data.forEach(
              (item) => dashGridExpireText.add(item['offer_expiry_date']));
          print("Main Text Count: ${dashGridMainText.length}");
          print("Image Count: ${dashGridImages.length}");
          print("Expire Text Count: ${dashGridExpireText.length}");
          print("Data Type: $data");
          setState(() {
            isDataLoaded = true;
          });
      }
    } catch (e) {
      print(e);
    }
  }

// Container where GridView is rendered:

Container(
  height: SizeConfig.blockSizeVertical * 55,
  width: SizeConfig.blockSizeHorizontal * 95,
  child: isDataLoaded ?
  GridView.builder(
    gridDelegate:
    SliverGridDelegateWithFixedCrossAxisCount(
      childAspectRatio:
      (SizeConfig
        .blockSizeHorizontal /
        SizeConfig.blockSizeVertical) *
      1.4,
      mainAxisSpacing:
      SizeConfig.blockSizeVertical * 1,
      crossAxisSpacing: 2.0,
      crossAxisCount: 3),
    itemCount: dashGridImages.length,
    itemBuilder: (context, index) {
      return Card(
        elevation: 4,
        shape: RoundedRectangleBorder(
          borderRadius:
          BorderRadius.all(Radius.circular(10.0)),
        ),
        color: dashGridColors[index],
        child: Column(
          children: [
            ClipRRect(
              borderRadius: BorderRadius.circular(10.0),
              child: Image.network(
                dashGridImages[index],
                fit: BoxFit.cover,
                height:
                SizeConfig.blockSizeVertical * 12,
              ),
            ),
            SizedBox(
              height:
              SizeConfig.blockSizeVertical * 1),
            Text(
              dashGridMainText[index],
              style: TextStyle(
                fontSize: smallTextSize,
                color: index != 4 ?
                Colors.white :
                Colors.grey[700],
                wordSpacing: -0.7),
              textAlign: TextAlign.center,
            ),
            SizedBox(
              height:
              SizeConfig.blockSizeVertical * 1),
            Text(
              dashGridExpireText[index],
              style: TextStyle(
                fontSize: ultraSmallTextSize,
                color: index != 4 ?
                Colors.black :
                Colors.grey[700],
              ),
              textAlign: TextAlign.center,
            ),
          ],
        ),
      );
    }) :
  Center(child: CircularProgressIndicator()),
),
CodeSadhu
  • 376
  • 2
  • 4
  • 15
  • are you calling fetchOffers() from build method? – VipiN Negi May 23 '21 at 07:53
  • Yeah I guess... fetchOffers is being called inside AsyncLoader body. AsyncLoader is called inside build method. – CodeSadhu May 23 '21 at 07:58
  • Do not make api calls from build method. When a page renders, it calls build method several times (expected behaviour), that calls your fetOffers multiple time as well. You should call it from initState() – VipiN Negi May 23 '21 at 08:01
  • @VipiNNegi I don't know how to do this with the AsyncLoader. AsyncLoader has compulsory field which requires you to give it a future – CodeSadhu May 23 '21 at 08:02
  • @VipiNNegi Can you please tell me how I could do the same code without using an AsyncLoader? I don't know how to use a FutureBuilder in this case... – CodeSadhu May 23 '21 at 08:03
  • are you trying to display some sort of loader while the data is being fetched from networK? – VipiN Negi May 23 '21 at 08:06
  • Yes, I'm showing a CircularProgressIndicator till data is being fetched – CodeSadhu May 23 '21 at 08:08

1 Answers1

0

As I understand from the comments, you can implement this simply with ternary operator. This below example is just basic implementation

import 'package:flutter/material.dart';

class Example extends StatefulWidget {
  @override
  _ExampleState createState() => _ExampleState();
}

class _ExampleState extends State<Example> {
  bool isDataFetched = false;
  String data;

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    getData();
  }
  
  getData() async {
    var offerResponse;
    try{
      offerResponse = await http.get(offers);
      if (offerResponse.statusCode == 200) {
        setState(() {
          data = offerResponse['data'];
          isDataFetched = true;
        });
      }
    } catch(e){
      print(e);
    }
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: isDataFetched ?
      Text(data,):
      CircularProgressIndicator(),
    );
  }
}
VipiN Negi
  • 2,994
  • 3
  • 24
  • 47