I'm working on a Flutter project which uses GetX for state management.
We have some entities which contains List properties. A simplified version would be similar to this:
class UserFees extends Equatable {
final String userId;
final List<double> fees;
UserFees({required this.userId, this.fees = const []});
void addFee(double newFee) => fees.add(newFee);
@override
List<Object> get props => [fees];
// Alternatively, we have also tried to:
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is UserFees &&
runtimeType == other.runtimeType &&
listEquals(fees, (other as UserFees).fees);
@override
int get hashCode => // I do not remember the calculus we'd used,
// but it did at least change when new item was added;
}
This entity is used in the controller:
class MyController extends GetxController {
final Rx<UserFees> userFees;
void addFee(double newFee) {
userFees.addFee(newFee);
// We have tried calling update() to no effect
}
}
When I use this inside a Widget with Obx, it doesn't rebuild when I add an item to the list, even though the object's hashCode gets updated.
Widget build(BuildContext context) {
return Scaffold(
body: Obx(() => Column(children:
...controller.userFees.fees.map(
(item) => Text(item.toString()
);
),
),
floatingActionButton: IconButton(
icon: const Icon(Icons.add),
onPressed: controller.addFee(0.1)
),
);
);
}
Our team has made this work by turning the List inside the entity into an RxList, however it's not ideal because we did not want to couple our entities with GetX or RxDart.
GetX documentation is pretty poor on these details, and the source code ir pretty hard to understand, at least for me. So, can anyone explain to me how is it that Obx knows that an observable object has changed? Does it look at the hashCode? Will it only rebuild if my class is immutable, and I rebuild the object entirely when adding an item to the list?