felangel / equatable

A Dart package that helps to implement value based equality without needing to explicitly override == and hashCode.
https://pub.dev/packages/equatable
MIT License
901 stars 100 forks source link

Equatable doesn't checks for Equality for variables in parent class #143

Closed LeeBoonKong closed 1 year ago

LeeBoonKong commented 1 year ago

I have a state bloc

abstract class BaseState extends Equatable{
    List<MyObject> listA;
    List<MyObject> listB;
    BaseState(this.listA, this.listB);

    @override
    List<Object> get props => [listA, listB]
}

class StateA extends BaseState{
    BaseState(List<MyObject> newListA, List<MyObject> newListB): super(List.of(newListA), List.of(newListA));
}

As the example above, while receiving StateA from BlocBuilder using flutter_bloc, Equatable is not able to detect the difference in StateA hence the UI is not updated.

Is my implementation and the way of using Equatable correct in this regard?

RobertPietraru commented 1 year ago

An year late, but does MyObject extend Equatable? If it doesn't it won't work

hussendev commented 1 year ago

Fixing that, your code should look like this:

class StateA extends BaseState {
    StateA(List<MyObject> newListA, List<MyObject> newListB)
        : super(List.of(newListA), List.of(newListB));
}

Your implementation of Equatable in the BaseState class appears to be correct. By extending Equatable and overriding the props getter to include listA and listB, you're instructing Equatable to take those properties into account when determining equality between two instances of BaseState.

However, there is one modification needed in the BaseState class. It is recommended to mark the listA and listB fields as final and ensure that they are assigned values in the constructor. This ensures immutability and guarantees that the values of listA and listB cannot be changed once set. Here's the updated code:

abstract class BaseState extends Equatable {
  final List<MyObject> listA;
  final List<MyObject> listB;

  BaseState(this.listA, this.listB);

  @override
  List<Object> get props => [listA, listB];
}

class StateA extends BaseState {
  StateA(List<MyObject> newListA, List<MyObject> newListB)
      : super(List.of(newListA), List.of(newListB));
}
felangel commented 1 year ago

Closing this issue for now since it's quite old. Feel free to comment if you're still having trouble and I'm happy to take a closer look, thanks!