1

I am pretty new in flutter. I don't know what happening in background because after hot reload its work fine. On another dart files that happens, firebase dont provide me data on initialization just after hot reload.

class CityServices {
      getCites() {
        return Firestore.instance.collection('cities').getDocuments();
      }
    }

class _HomeScreenState extends State<HomeScreen> {
  bool citiesFlag = false;
  var cities;
  int citiesCount;
  String actualCity;

Maybe mistake is here.

  @override
  void initState() {
    super.initState();
    CityServices().getCites().then((QuerySnapshot) {
      if (QuerySnapshot.documents.isNotEmpty) {
        citiesFlag = true;
        cities = QuerySnapshot.documents;
        citiesCount = QuerySnapshot.documents.length;
      }
    });
  }


  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        backgroundColor: MyColors.vintageGreen,
        appBar: AppBar(
          backgroundColor: MyColors.background,
          title: Center(
            child: Text(
              'Válasszon települést...',
              style: GoogleFonts.barlowCondensed(
                  color: MyColors.appbarText,
                  fontSize: 26.0,
                  fontWeight: FontWeight.w500),
            ),
          ),
        ),
        body: Center(
          child: Container(
            child: GridView.count(
              crossAxisCount: 2,
              children: List.generate(citiesCount, (index) {
                return Card(
                  shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.all(Radius.circular(10)),
                  ),
                  child: InkWell(
                    onTap: () {
                      actualCity = cities[index]['city_name'];
                      Navigator.push(
                        context,
                        MaterialPageRoute(
                            builder: (context) =>
                                CityView(cityName: actualCity)),
                      );
                    },
                    child: Column(
                      mainAxisSize: MainAxisSize.min,
                      children: <Widget>[
                        ListTile(
                          title: Center(
                              child: Text(
                            cities[index]['city_name'],
                            style: TextStyle(
                                fontWeight: FontWeight.w500, fontSize: 18.0),
                          )),
                          subtitle: Center(child: Text('22 bejegyzés')),
                        ),
                        Flexible(
                          child: ClipRRect(
                            borderRadius: BorderRadius.all(Radius.circular(5)),
                            child: Padding(
                              padding: EdgeInsets.only(bottom: 15.0),
                              child: Image(
                                image: AssetImage(
                                  cities[index]['img_path'],
                                ),
                              ),
                            ),
                          ),
                        )
                      ],
                    ),
                  ),
                  color: MyColors.background,
                );
              }),
            ),
          ),
        ),
      ),
    );
  }
}

Maybe here is the mistake? Should it be on top of dart file?

class HomeScreen extends StatefulWidget {
  static const String id = 'home';
  @override
  _HomeScreenState createState() => new _HomeScreenState();
}
James Z
  • 12,209
  • 10
  • 24
  • 44
Prahaan
  • 13
  • 5

1 Answers1

0

Let me explain the issue and why it is happening, then propose few solutions.

inside initState you are calling CityServices().getCites().then... which is an async method.
However, when your widget is built for the first time, the data you expect from Firestore is not ready yet, thus you get null for both cities and citiesCount.

Short term solution:
make sure there is null check, display indicator while waiting for the data.

body: Center(
   child: (cities == null) ? 
     CircularProgressIndicator()
     : Container(...

Additionally, you can also refactor your initState to something like this

void getCities() async {
   var snapshot CityServices().getCites();
   setState(() {
        citiesFlag = true;
        cities = snapshot.documents;
        citiesCount = snapshot.documents.length;
      });
}

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

Long term solution:
use BLoC pattern and make data loading decoupled from UI.
see flutter_bloc for how to implement it.

Yilmaz Guleryuz
  • 9,313
  • 3
  • 32
  • 43
  • Error message has gone. But now, at the start of application, the Indicatior spinning and spinning, and my app has not started. This is my main.dart file. void main() => runApp(JaszEtlap()); class JaszEtlap extends StatelessWidget { final appTitle = 'A JÁSZSÁG ÉTLAPJA'; @override Widget build(BuildContext context) { return MaterialApp( initialRoute: HomeScreen.id, routes: {HomeScreen.id: (context) => HomeScreen()}, ); } } – Prahaan Aug 21 '20 at 20:32
  • sounds good. I just updated my answer with additional example. – Yilmaz Guleryuz Aug 22 '20 at 09:21
  • btw. the way you deal with async data, aka data loaded from Firestore, needs to be decoupled from UI. For that reason, I recommend you using `flutter_bloc`, see the link shared in the answer. – Yilmaz Guleryuz Aug 22 '20 at 09:22
  • plz remember to accept and vote the answer if it resolves your question. see guidelines https://stackoverflow.com/help/someone-answers – Yilmaz Guleryuz Aug 22 '20 at 09:24