Adding and Removing items from a list using provider flutter

Issue

I’m making favorite list which contains the user favorite journeys using provider then I will display these journeys in the favorite journeys screen.

Favorite.dart:

import 'package:flutter/material.dart';

class Favorite extends ChangeNotifier {
  final Text date;
  final Text time;
  final Text source;
  final Text destination;
  final Text price;

  Favorite(this.date, this.time, this.source, this.destination, this.price);
}

class Following extends ChangeNotifier {
  List<Favorite> list = [];
  add(favorite) {
    list.add(favorite);
    notifyListeners();
  }

  remove(favorite) {
    list.remove(favorite);
    notifyListeners();
  }
}

journeys.dart (Which shows all journeys):

   FirebaseAnimatedList(
                      shrinkWrap: true,
                      query: Consts.journeyRef.child("journeys"),
                      itemBuilder: (BuildContext context, DataSnapshot snapshot,
                          Animation animation, int index) {
                        try {
                          return Consumer<Following>(
                            builder:
                                (BuildContext context, value, child) {
                              return Dismissible(
                                key: UniqueKey(),
                                secondaryBackground: buildSwipeActionRight(),
                                background: buildSwipeActionLeft(),
                                child: ListView(
                                    scrollDirection: Axis.vertical,
                                    shrinkWrap: true,
                                    children: <Widget>[
                                      eachTile(
                                        following,
                                        Favorite(
                                        Text(Map<String, dynamic>.from(
                                          snapshot.value as Map)[Consts.pathDateJourney]),
                                        Text(Map<String, dynamic>.from(
                                            snapshot.value as Map)[Consts.pathTimeJourney]),
                                        Text(Map<String, dynamic>.from(
                                            snapshot.value as Map)[Consts.pathSourceCity]),
                                        Text(Map<String, dynamic>.from(
                                            snapshot.value as Map)[Consts.pathDestinationCity]),
                                        Text(Map<String, dynamic>.from(
                                            snapshot.value as Map)[Consts.pathPriceJourney]),),)
        
                                    ]),
                                onDismissed: (direction) =>
                                    dismissItem(context, index, direction),
                              );
                            },
                          );
                        } catch (e) {
                          customSnackBar(context, e.toString(), 3, Colors.white24, Colors.brown, 17);
                          return const Text(
                              "We Can't show you information disabled by the Administrator");
                        }
                      }),

eachTile.dart:

ListTile eachTile(following, favorite) {
  return ListTile(
    leading: Column(
      children: [
        favorite.date,
        const SizedBox(
          height: 10,
        ),
        favorite.time,
      ],
    ),
    title: Row(
      children: [
        favorite.source,
        const SizedBox(
          width: 50,
        ),
        favorite.price
      ],
    ),
    subtitle: favorite.destination,
    trailing: IconButton(
      icon: following.list.contains(favorite)
          ? const Icon(Icons.favorite)
          : const Icon(Icons.favorite_border_outlined),
      onPressed: () {
        print(following.list.contains(favorite));
// this print statement always false
        if (following.list.contains(favorite)) {
          following.remove(favorite);
        } else {
          following.add(favorite);
        }
        print(following.list.contains(favorite));
// this print statement always true
        print(following.list);
// this print statement print the list and in each time the code execute new instance added to the list
      },
    ),
  );
}

This code is working fine as adding the journey to the list but the Problem is that when you click on the favorite icon again the condition

following.list.contains(favorite)

is returning false (Which means this object is not in the list but that’s wrong I try to print the list and there is an instance) it seem that the following instance changed but I didn’t create any new instance I think it is creating new different instance in each time.

What is the best way to add and remove items to the favorite list using provider?

the output:

I/flutter (  578): false
I/flutter (  578): true
I/flutter (  578): [Instance of 'Favorite']
V/AutofillManager(  578): requestHideFillUi(null): anchor = null
I/flutter (  578): false
I/flutter (  578): true
I/flutter (  578): [Instance of 'Favorite', Instance of 'Favorite']
V/AutofillManager(  578): requestHideFillUi(null): anchor = null
I/flutter (  578): false
I/flutter (  578): true
I/flutter (  578): [Instance of 'Favorite', Instance of 'Favorite', Instance of 'Favorite']

Solution

The problem was that I’m making equal-to operator between two object and it’s returning false that is because all objects in the dart language except the primitive data types like string, int, and double… are not equal to each other since no == operator is overridden and set to it, and this include also collections like lists, maps…
the solution is to override the == operator in Favorite class:

class Favorite{
  final Text date;
  final Text time;
  final Text source;
  final Text destination;
  final Text price;
  Favorite(this.date, this.time, this.source, this.destination, this.price);@override
  bool operator == (Object other) {
    return other is Favorite && date.toString() == other.date.toString() && time.toString() == other.time.toString() && source.toString() == other.source.toString() && destination.toString() == other.destination.toString() && price.toString() == other.price.toString();
  }
}

now when I run following.list.contains(favorite) or following.list[0]==favorite in listTile Widget it will return true.
and that’s it

Answered By – saad tabban

Answer Checked By – David Goodson (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *