2

I have a collection of dishes.

I want to retrieve all restaurant who have a specific list of dish in his menu.

My data model is this:

restaurant---->rest1
      |         |-->menu
      |                   | --> 1: true
      |                   | --> 2: true
      |                   | --> 3: true
      |--->rest2
      |         |-->menu
      |                   | --> 1: true
      |                   | --> 2: true
      |                   | --> 3: true
      |--->rest3
      |         |-->menu
      |                   | --> 1: true


my list of dishes is [1,2] for this reason I want to retrieve only rest1 and rest2

my code is this:

Future loadRestaurantsByDishes({List idPiatti})async{


    idPiatti.forEach((element) async {
      dynamic result2 = await _restaurantServices.getRestaurantOfDish(id_piatto: element["dishId"].toString());
      rest.add( result2);
    });
    if(rest.length >0){
      List<RestaurantModel> mom = [];
      List<RestaurantModel> temp = [];
      rest.forEach((item) {
        if(mom.isEmpty){
          mom.addAll(item);
        }else{
          temp.addAll(item);
          mom.removeWhere((element) => !temp.contains(element));
          temp = [];
        }

      });
      notifyListeners();
    }
  }


Future<List<RestaurantModel>> getRestaurantOfDish({String id_piatto}) async =>
      _firestore.collection(collection).where("menu."+id_piatto, isEqualTo: true).get().then((result) {
        List<RestaurantModel> restaurants = [];
        for (DocumentSnapshot restaurant in result.docs) {
          restaurants.add(RestaurantModel.fromSnapshot(restaurant));
        }
        return restaurants;
      });


My idea is to retrieve all resturant who made a specific dish and after retrieve the common elements between those lists in order to retrieve the only restaur ant which have all of them.

The problem is that mom in the first statement is equal to item, but when I run mom.removeWhere((element) => !temp.contains(element)); it returns an empty list.

Where I'm getting wrong?

Thank you

Nisanth Reddy
  • 5,967
  • 1
  • 11
  • 29
GTF
  • 125
  • 10
  • Hi there. Try making a reproducible demo using `https://dartpad.dev/` if possible. You question seems to be more about manipulating lists rather than `firebase`. So try creating basic sample list and try to perform the manipulation you are trying in the dartpad. – Nisanth Reddy May 18 '21 at 07:39
  • yes, the problem is in manipulation of strings in order to go forward to firebase limitation :), I used the pad and on basic list, my code seems to work, the problem is with list of custom object. – GTF May 18 '21 at 07:49
  • You define your custom objects in dart pad and create sample custom objects ? wouldn't that help making a demo ? – Nisanth Reddy May 18 '21 at 07:50
  • I tried also in this way `void main() { List l1 = [ { "catId": '1' }, { "catId": '2' }, ]; List l2 = [{ "catId": '2' }, { "catId": '3' }, ]; List l3 = [{ "catId": '2' }, { "catId": '4' }, ]; l1.removeWhere((item) => !l2.contains(item)); l1.removeWhere((item) => !l3.contains(item)); print(l1); }` but I obrtain the empty one – GTF May 18 '21 at 07:54
  • Yes, it is giving `[]`. Now can you explain what output you expect ? – Nisanth Reddy May 18 '21 at 07:58
  • I want to retrieve common elements, in case of question `rest1` and `rest2`, while in case of dart pad `"catId":2` – GTF May 18 '21 at 08:00
  • This is because trying to compare Map will give that two cats with same id are not same because they don't have an `==` operator overload. Check out my answer. – Nisanth Reddy May 18 '21 at 08:24

1 Answers1

3

While comparing objects of custom classes you have created, you must override the == override and the hashCode function.

You can use the below explained method for you own custom classes in order to compare two of them using the == operator.

Try running this inside a DartPad.

class Cat {
  String id;
  Cat(this.id);

  @override
  bool operator == (Object other){
    return other is Cat && id == other.id;
  }

  @override
  int get hashCode => id.hashCode;

  @override
  String toString() => '{ id: $id }';

}

void main() {
  List l1 = [Cat('1'), Cat('2')];
  List l2 = [Cat('2'), Cat('3')];
  List l3 = [Cat('2'), Cat('4')];

  l1.removeWhere((item) => !l2.contains(item));
  l1.removeWhere((item) => !l3.contains(item));
  print(l1);
}
Nisanth Reddy
  • 5,967
  • 1
  • 11
  • 29
  • Cool! I forgot the override method for == and hashcode! Thank you so much! – GTF May 18 '21 at 15:39
  • @GTF Glad to have helped :) . This is a good question so I have upvoted it. People might have a similar problem. So I have edited the question to add correct tags and heading. If you feel the answer is adequate, please consider upvoting it as well so that it may reach more people. – Nisanth Reddy May 18 '21 at 15:56