Jeevan Crasta
Jeevan Crasta

Reputation: 113

How to display data in listview using StreamBuilder from Realtime DB in flutter

I am developing an app for my college project and I am stuck in an error. I am using realtime DB to store data. I am Using a listView to display all the availble data in the db.My DB looks like this When ever I try to retrieve data from DB if the data is available then it gets loaded. But, if there is no data available(I mean If the PlantData is not available) Then it Shows this error

This is my Code

final dbRef = FirebaseDatabase.instance
      .reference()
      .child("IDh04V383uYGQQfWlVWp2XsdR0J3")
      .child("PlantData");

  List lists = List();


@override
  Widget build(BuildContext context) {
    return Scaffold(
      
      body: Container(
        child: StreamBuilder(
          stream: dbRef.onValue,
          builder: (context, AsyncSnapshot<Event> snapshot) {
            if (snapshot.hasData) {
              print("Error on the way");
              lists.clear();
              DataSnapshot dataValues = snapshot.data.snapshot;
              Map<dynamic, dynamic> values = dataValues.value;
              values.forEach((key, values) {
                lists.add(values);
              });
              return new ListView.builder(
                shrinkWrap: true,
                itemCount: lists.length,
                itemBuilder: (BuildContext context, int index) {
                  return Card(
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: <Widget>[
                        Text("Name: " + lists[index]["smartID"]),
                        Text("Image: " + lists[index]["plantname"]),
                      ],
                    ),
                  );
                },
              );
            }
            return Container(child: Text("Add Plants"));
          },
        ),
      ),
      
    );

Upvotes: 0

Views: 3979

Answers (1)

Tarik Huber
Tarik Huber

Reputation: 7388

As @Uni mentioned you can provide the initialData to your StreamBuilder but I would also recommend to always write your code to be prepared for every case the state can have like so:

final dbRef = FirebaseDatabase.instance
      .reference()
      .child("IDh04V383uYGQQfWlVWp2XsdR0J3")
      .child("PlantData");

  List lists = List();


@override
  Widget build(BuildContext context) {
    return Scaffold(
      
      body: Container(
        child: StreamBuilder(
          stream: dbRef.onValue,
          builder: (context, AsyncSnapshot<Event> snapshot) {
            if (snapshot.hasData && !event.hasError &&
            event.data.snapshot.value != null) {
              print("Error on the way");
              lists.clear();
              DataSnapshot dataValues = snapshot.data.snapshot;
              Map<dynamic, dynamic> values = dataValues.value;
              values.forEach((key, values) {
                lists.add(values);
              });
              return new ListView.builder(
                shrinkWrap: true,
                itemCount: lists.length,
                itemBuilder: (BuildContext context, int index) {
                  return Card(
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: <Widget>[
                        Text("Name: " + lists[index]["smartID"]),
                        Text("Image: " + lists[index]["plantname"]),
                      ],
                    ),
                  );
                },
              );
            }
            return Container(child: Text("Add Plants"));
          },
        ),
      ),
      
    );

You should also handle the state when your data is loading and also when you have an error. That way you should not get any surprises.

Upvotes: 2

Related Questions