I’m having issues accessing my Map state to get the length of the list MartialArtsMove.hand.
Here is my class/provider:
import 'package:flutter_riverpod/flutter_riverpod.dart';
enum MartialArtsMove {
hand,
kick,
grab;
}
class OneSteps extends Notifier<Map<MartialArtsMove, List<num>>> {
@override
Map<MartialArtsMove, List<num>> build() =>
{for (final k in MartialArtsMove.values) k: <num>[]};
void setMove(MartialArtsMove martialArtsMove, List<num> items) {
state[martialArtsMove] = items;
ref.notifyListeners();
}
void clearAll() {
for (final martialArtsMove in MartialArtsMove.values) {
state[martialArtsMove]!.clear();
}
ref.notifyListeners();
}
}
final oneStepsProvider = StateProvider<OneSteps>((_) => OneSteps());
and here is how I use it on my page:
var oneStepState = ref.watch(oneStepsProvider);
Text(
'Hands ${oneStepState.state[MartialArtsMove.hand]!.length}',
textAlign: TextAlign.center,
// overflow: TextOverflow.ellipsis,
style: const TextStyle(fontSize: 14),
)
I have also tried
Text(
'Hands ${oneStepState[MartialArtsMove.hand]!.length}',
textAlign: TextAlign.center,
// overflow: TextOverflow.ellipsis,
style: const TextStyle(fontSize: 14),
)
2
Answers
StateProvider is the right Provider for cases where you simply want to read and write values.
For cases like the above, you can use a NotifierProvider to have a defined action (method) update the state.
You can read more about this below.
You’re creating a
Notifier
but then exposing it through aStateProvider
. Those classes are not designed to work together, and in fact the code you shared contains a linter warning that you shouldn’t accessNotifier.state
from outside the class. The simplest fix is to change your provider type toNotifierProvider
and update your ref usage to retrieve the notifier and its state separately:Here’s a working Dartpad demonstrating the changes + some other misc refactoring like making the state immutable, which is a bit more idiomatic in Riverpod.