Home > front end >  Flutter arrayContainsAny search resulting in duplicate documents being returned, am I querying wrong
Flutter arrayContainsAny search resulting in duplicate documents being returned, am I querying wrong

Time:11-18

Here is my code: I am successfully getting the search results, but there are duplicate documents/products being added to the list. I'm not sure exactly why this is happening. Any help would be appreciated. I am searching an array to perform a "lazy search" type functionality in my app, so how do I remove the duplicates?

  List<Map<String, dynamic>> products = [];
  bool searching = false;

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Expanded(
          child: !searching
              ? Container()
              : ListView.builder(
                  itemCount: products.length,
                  itemBuilder: ((context, index) {
                    return ProductWidget(
                        price: products[index]['price'],
                        name: products[index]['name'],
                        uid: products[index]['uid'],
                        image: products[index]['image'],
                        description: products[index]['description'],
                        title: products[index]['title'],
                        purchase: false,
                        showDescription: false,
                        doListView: false,
                        id: products[index]['id']);
                  })),
        ),
        Container(
          width: MediaQuery.of(context).size.width,
          color: Colors.white,
          child: Padding(
            padding: const EdgeInsets.all(8.0),
            child: Row(
              children: [
                const Icon(Icons.search),
                Expanded(
                  child: TextField(
                    style: const TextStyle(color: Colors.black),
                    onChanged: (val) {
                      _initiateSearch(val);
                    },
                    decoration: const InputDecoration(
                        hintStyle: TextStyle(color: Colors.black),
                        border: InputBorder.none,
                        hintText: 'Search products'),
                  ),
                ),
              ],
            ),
          ),
        )
      ],
    );
  }

  _initiateSearch(String val) async {
    try {
      if (val.length == 0) {
        setState(() {
          searching = false;
          products.clear();
        });
      } else {
        setState(() {
          searching = true;
          products.clear();
        });

        List array = val.split('');

        var items = await FirebaseFirestore.instance
            .collection('products')
            .where('search_array', arrayContainsAny: array)
            .orderBy('timestamp', descending: false)
            .limit(10)
            .get();

        for (int i = 0; i < items.docs.length; i  ) {
          products.add({
            'price': items.docs[i].data()['price'],
            'name': items.docs[i].data()['name'],
            'uid': items.docs[i].data()['uid'],
            'image': items.docs[i].data()['image'],
            'description': items.docs[i].data()['description'],
            'title': items.docs[i].data()['title'],
            'id': items.docs[i].id
          });
        }

        setState(() {});
      }
    } catch (e) {}
  }

CodePudding user response:

Clear the list on search and then add items.

_initiateSearch(...){
  ....
  products.clear();
   for (int i = 0; i < items.docs.length; i  ) {
          products.add({
  ....

A better option will be returning list and then use it, while detecting use case of products can be tricky.

  • Related