I have an itemCount
map with an ItemDescription
keys and int
values.
Map<ItemDescription, int> itemCount = {
ItemDescription(
name: 'Pepsi',
price: 10,
): 1,
ItemDescription(
name: 'Coca-Cola',
price: 12,
): 1,
};
I want to update the int
value of the map in various places throughout my code, so I have defined the functions increment
and decrement
in a StateNotifier
:
class ItemCountQuantity extends StateNotifier<Map<ItemDescription, int>> {
ItemCountQuantity() : super(itemCount);
void decrement(int index) {
state.update(
state.keys.elementAt(index),
(value) {
return --value;
},
);
}
void increment(int index) {
state.update(
state.keys.elementAt(index),
(value) {
return value;
},
);
}
}
The StateNotifierProvider
for the above is defined as such:
final itemCountQuantity =
StateNotifierProvider<ItemCountQuantity, Map<ItemDescription, int>>(
(ref) => ItemCountQuantity(),
);
When I am calling ref.read(itemCountQuantity.notifier).decrement(index);
or ref.read(itemCountQuantity.notifier).increment(index);
in the onPressed
parameter of a button, I can see that the value is updating but the state is not. Is there some error in my StateNotifier
?
EDIT:
I tried setting the StateNotifier as such:
class ItemCountQuantity extends StateNotifier<Map<ItemDescription, int>> {
ItemCountQuantity() : super(itemCount);
void decrement(int index) {
state = {
...state,
state.keys.elementAt(index):
state[state.keys.elementAt(index)]! - 1
};
}
void increment(int index) {
state = {
...state,
state.keys.elementAt(index):
state[state.keys.elementAt(index)]! 1
};
}
}
But neither did this work.
CodePudding user response:
Your issue is that you’re missing:
state = Map.of(state.update(…));
// instead of just
state.update(…);
This is because you need to assign the state to a new value so the StateNotifier knows something was updated. (state is implemented as a getter and setter under the hood.)
However, I’d like to note that doing state.keys.elementAt(index) feels very wrong when using a map, as it relies on the implementation of the map. If you must use the index to access an element, use a list of tuples. Or, just reference the map using its keys (and not an index).
CodePudding user response:
When you access your provider have you tried using the watch()
method?
ref.read(itemCountQuantity.notifier).decrement(index)
to
ref.watch(itemCountQuantity.notifier).decrement(index)
read()
will only get the value of/in provider just once (one-time read)
watch()
get the value of/in provider the first time and every time the value changes