Flutter Bloc equatable state not updating with a Map of Strings property
Asked Answered
A

2

6

My Bloc state isn't updating and I've found the problem to potentially be a Map<String, Map<String, String> property that isnt being compared properly. Please correct me if I'm wrong, but the state updates when the other properties change, just not when the imageUrls property updates.

These are my state objects

abstract class PropertiesState extends Equatable {
  const PropertiesState();
}

class PropertiesLoaded extends PropertiesState {
  final int count;
  final List<Property> properties;
  final Map<String, Map<String, String>> imageUrls;

  const PropertiesLoaded({
    this.count,
    this.properties,
    this.imageUrls,
  });

  @override
  List<Object> get props => [count, properties, imageUrls];
}

The imageUrls field can have any string key/value pairs. I haven't been able to find any information on how I should do this.

Thanks for the help!

Assiniboine answered 14/7, 2020 at 12:52 Comment(2)
I think it should work well, however, change Map<String, Map<String, String>> to dynamic, just as a test, Tell me the resultRoughen
You're right it does work. Maps compare easily. Turns out I was changing a property on the imageUrl instead of creating a new map with each event. I get why properties on classes need to be immutable for equatable to work now tooAssiniboine
T
7

Because Equatable is trying to compare the reference of your List or Map object because they are not primitive type like int. You can try deep copy a Map object (using Map.from()) and replace the old one, and use hash code to do the comparison.

Tantalus answered 8/1, 2021 at 2:9 Comment(2)
how to use hash code to do the comparison?Done
@Done pass in equatable props hashCode instead of just map property. In this example it would be: List<Object> get props => [count, properties, imageUrls.hashCode];Medalist
N
6

From Docs

Equatable properties should always be copied rather than modified. If an Equatable class contains a List or Map as properties, be sure to use List.from or Map.from respectively to ensure that equality is evaluated based on the values of the properties rather than the reference.

emit(PropertiesLoaded(count, properties,
Map<String, Map<String, String>>.from(imageUrls)));
Nonconformity answered 10/8, 2022 at 11:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.