delmin
delmin

Reputation: 2700

Get certain documents data from firestore to populate dropdown

I'm trying to populate my dropdown with firestore data. I want to do it as light as possible without any stream builder sorting or any other things I don't need. I have created reusable call in my services to firestore to get only documents I want

  Future<List<Map<String, dynamic>>> getCollections<T>(String path) async {
    final data = await Firestore.instance.collection(path).getDocuments();
    final result = data.documents.map((doc) => doc.data).toList();
    return result;
  }

And I use it in my database to get collections at certain path

  Future<List<Map<String, dynamic>>> brandStream() =>
      _service.getCollections('all_brands');

And then call it for now in my button to print the data

           onPressed: () async {
              final database =
                  Provider.of<Database>(context, listen: false);
              var r = await database.brandStream();
              print(r);
            }

It all works but obviously it also pull data which I'm not interested in. I only need from each collection to get name and image url but I get all other things which are in that collection. What is the best way of doing it? I can't work out how to add the data into a model class which only contains name and url (as from my previous question) Return List of <T> from firestore collections

Upvotes: 0

Views: 55

Answers (1)

LonelyWolf
LonelyWolf

Reputation: 4392

You have to include T builder in your service file like this

  Future<List<T>> getCollections<T>(
      {String path,
      @required
          T builder(Map<String, dynamic> data, String documentID)}) async {
    final data = await Firestore.instance.collection(path).getDocuments();
    final result =
        data.documents.map((doc) => builder(doc.data, doc.documentID)).toList();
    return result;
  }

then in your database file use the builder to add the data to your model class

  @override
  Future<List<Brand>> brandStream() => _service.getCollections(
      path: 'tool_bank', builder: (data, id) => Brand.fromMap(data, id));

where your model class should look like this

class Brand {
  String logo, name, bid;
  Brand({this.logo, this.name, this.bid}); 

  factory Brand.fromMap(Map<String, dynamic> brandData, String documentID) {
    if (brandData == null) {
      return null;
    }
    final String logo = brandData['logo'];
    final String name = brandData['logo'];

    return Brand(logo: logo, name: name, bid: documentID);
  }
}

Then you can use it same way as you use it

Upvotes: 1

Related Questions