For filter my list I use a state FilterState.
I have in this state my list filter but my widget for build list is not rebuild.
My print shows that the list is correct according to the state.
But GameList
keeps its initial state which is not filtered : it's not rebuild.
Thanks,
my page for state :
BlocBuilder<GameBloc, GameState>(
builder: (context, state) {
if (state is LoadingState) {
return buildLoading();
} else if (state is FailState) {
return ErrorUI(message: state.message);
} else if (state is ListLoadedState) {
_list = state.list;
return GameList(list: state.list!);
} else if (state is FilterGamesState) {
print(state.list);
return GameList(list: state.list!);
}
return Container();
},
),
Bloc Page :
class GameBloc extends Bloc<GameEvent, GameState> {
GameBloc({required this.repository}) : super(LoadingState()) {
on<BackEvent>(_onBackEvent);
on<FetchGamesEvent>(_onFetchList);
on<FetchGameEvent>(_onFetchItem);
on<SavingEvent>(_onSavingEvent);
on<UpdateGameEvent>(_onUpdate);
on<CreateGameEvent>(_onCreate);
on<FilterGamesEvent>(_onFilter);
}
GameRepository repository;
final currentFilter = BehaviorSubject<Map<String, dynamic>>();
Future<void> _onFilter(
FilterGamesEvent event,
Emitter<GameState> emit,
) async {
try {
emit(LoadingState());
final list = event.list?.where((Game item) {
if (currentFilter.value.containsKey('player')) {
int players = currentFilter.value['player'].nb;
return players.isBetween(from: item.nopMin, to: item.nopMax);
}
return true;
}).where((Game item) {
if (currentFilter.value.containsKey('age')) {
return item.age!.isBetween(
from: currentFilter.value['age'].min,
to: currentFilter.value['age'].max);
}
return true;
}).where((Game item) {
if (currentFilter.value.containsKey('duration')) {
return compareToDuration(
item.durMin!,
item.durMax!,
currentFilter.value['duration'].min,
currentFilter.value['duration'].max);
}
return true;
}).where((Game item) {
if (currentFilter.value.containsKey('tags')) {
return item.tags!
.compareToList(currentFilter.value['tags'] as List<String>);
}
return true;
}).where((Game item) {
if (currentFilter.value.containsKey('collection')) {
return item.collection!
.compareToList(currentFilter.value['collection'] as List<String>);
}
return true;
}).toList();
emit(FilterGamesState(listGame: list!));
} catch (e) {
emit(const FailState(message: 'Failed to fetch all games data.'));
}
}
Event Page :
abstract class GameEvent extends Equatable {
final Game? item;
const GameEvent({this.item});
@override
List<Object> get props => [];
}
class InitialEvent extends GameEvent {
const InitialEvent({required Game item}) : super(item: item);
}
class BackEvent extends GameEvent {}
class SavingEvent extends GameEvent {}
class FetchGameEvent extends GameEvent {
const FetchGameEvent({required Game item}) : super(item: item);
}
class FetchGamesEvent extends GameEvent {}
class FilterGamesEvent extends GameEvent {
const FilterGamesEvent({required this.list});
final List<Game>? list;
}
State Page :
abstract class GameState extends Equatable {
final Game? item;
final List<Game>? list;
const GameState({this.item, this.list});
@override
List<Object> get props => [];
}
class GameInitial extends GameState {}
class FailState extends GameState {
const FailState({required this.message});
final String message;
}
class LoadingState extends GameState {}
class ListLoadedState extends GameState {
const ListLoadedState({required this.listGame}) : super(list: listGame);
final List<Game> listGame;
}
class ItemLoadedState extends GameState {
const ItemLoadedState({required this.game}) : super(item: game);
final Game game;
}
class FilterGamesState extends GameState {
const FilterGamesState({required this.listGame}) : super(list: listGame);
final List<Game> listGame;
}
I resolved this,
I send the key to GameList in FilterGameState.
else if (state is FilterGamesState) {
print(state.list);
return GameList(key: GlobalKey<GameFilterState>(), list: state.list!);
}