Pulling data from QuerySnapshot in flutter

301 Views Asked by At

I need to populate a DropdownButton from a document in Firestore. I can retrieve the data. When I look into the snapshot.data I see 2 records which is what I expect to see. In the code below, everything works fine as long as I comment out the code snippet as you can see.

    Container(
                      child: StreamBuilder(
                          //stream: _firestoreService.getAgency(),
                          stream: _db.collection('agency').snapshots(),
                          builder: (BuildContext context, AsyncSnapshot snapshot) {
                            if (snapshot.data == null) {
                              return Center(
                                child: CircularProgressIndicator(),
                              );
                            } else {
                              //var length = snapshot.data.docs.length;
                              //print('length: ' + length);
                              return new DropdownButton<String>(
                                hint: new Text("Select Agency"),
                                value: _currentAgency,
    /*  <<<< The code below is where I am having problems
                                //onChanged: changedDropDownState,
                                **items: snapshot.data.docs.map((Map map) {
                                  return new DropdownMenuItem<String>(
                                    value: map["name"].toString(),
                                    child: new Text(
                                    map["name"],
                                    ),
                                  );
                                }).toList(),**
*/
                              );
                            }
                            ;
                          }),
                    ),

When I uncomment the code and run the app I get this error:

======== Exception caught by widgets library =======================================================
The following _TypeError was thrown building StreamBuilder<QuerySnapshot>(dirty, state: _StreamBuilderBaseState<QuerySnapshot, AsyncSnapshot<QuerySnapshot>>#d9273):
type '(Map<dynamic, dynamic>) => DropdownMenuItem<String>' is not a subtype of type '(QueryDocumentSnapshot) => dynamic' of 'f'

What I want to accomplish is to populate the value: attribute with the document ID but I don't see it in snapshot.data. The other thing I want to do is populate child: attribute with some of the values from the snapshot.data.

How do I do this?

2

There are 2 best solutions below

0
On

I found a post that says to use .forEach instead of map (Snapshot code inside StreamBuilder does not get executed when receiving data from Firebase FireCloud in Flutter).

This gets rid of the error but the DropdownButton is static and won't drop down or let me click on it. Here is my new code for the DropdownButton:

return new DropdownButton<String>(
                            hint: new Text("Select Agency"),
                            value: _currentAgency,
                            //onChanged: changedDropDownState,
                            items: snapshot.data.docs.forEach((document) {
                              return new DropdownMenuItem<String>(
                                value: document.data()['name'],
                                child: new Text(document.data()['name']),
                              );
                            }),
                          );

The data is there and I can see it when I debug. I want to get the documentId as well but I don't see that in the debugger.

How do I get the DropdownButton to be active and how do I add the documentId to the value: attribute?

0
On

Your issue is here

items: snapshot.data.docs.map(( ISSUE HERE===>Map map) {
  return new DropdownMenuItem<String>(
  value: map["name"].toString(),
  child: new Text(
  map["name"],
     ),
   );
 }).toList(),

The value for docs is QueryDocumentSnapshot and not type Map that is why you got the error message.

Instead, change it to this.

items: snapshot.data.docs.map((documentSnapshot) {
  return new DropdownMenuItem<String>(
  value: documentSnapshot["name"].toString(),
  child: new Text(
  documentSnapshot["name"],
     ),
   );
 }).toList(),