Flutter bloc - state not updating. Need reload screen

31 views Asked by At

I have app which is connected with firebase and has flutter bloc state management. Problem is when i try to change state. It's changing but changes are not visible - to reach it i have to reload screen

It's my state

class ShoppingListState extends Equatable {
  final List<ShoppingList> shoppingLists;
  final Map<String, List<ShoppingListItem>> shoppingListItems;
  const ShoppingListState({
    this.shoppingLists = const <ShoppingList>[],
    this.shoppingListItems = const <String, List<ShoppingListItem>>{},
  });

  ShoppingListState copyWith({
    List<ShoppingList>? shoppingLists,
  }) {
    return ShoppingListState(
      shoppingLists: shoppingLists ?? this.shoppingLists,
      shoppingListItems: shoppingListItems,
    );
  }

  @override
  List<Object> get props => [shoppingLists, shoppingListItems];

  Map<String, dynamic> toMap() {
    return {
      'shoppingLists': shoppingLists.map((e) => e.toMap()).toList(),
      'shoppingListItems': shoppingListItems.map(
        (k, v) {
          return MapEntry(k, v.map((e) => e.toMap()).toList());
        },
      ),
    };
  }

  factory ShoppingListState.fromMap(Map<String, dynamic> map) {
    return ShoppingListState(
      shoppingLists: List<ShoppingList>.from(
        map['shoppingLists']?.map((x) => ShoppingList.fromMap(x)) ?? [],
      ),
      shoppingListItems: Map<String, List<ShoppingListItem>>.from(
        map['shoppingListItems']?.map((k, v) {
              return MapEntry(
                k,
                List<ShoppingListItem>.from(
                  v.map((x) => ShoppingListItem.fromMap(x)),
                ),
              );
            }) ??
            {},
      ),
    );
  }
}

final class ShoppingListInitial extends ShoppingListState {}

and there is my function from bloc


  void _addItemToShoppingList(
      AddItemToShoppingList event, Emitter<ShoppingListState> emit) async {
    final List<ShoppingList> copiedShoppingLists =
        List.from(state.shoppingLists);
    ShoppingList shoppingList = copiedShoppingLists.firstWhere(
      (element) => element.id == event.shoppingListId,
    );
    shoppingList.list.add(event.shoppingListItem);

    await FirestoreRepository.updateShoppingList(shoppingList);

    final Map<String, List<ShoppingListItem>> copiedShoppingListItems =
        Map.from(state.shoppingListItems);
    List<ShoppingListItem> shoppingListItems =
        copiedShoppingListItems[event.shoppingListId]!;
    shoppingListItems.add(event.shoppingListItem);

    emit(
      ShoppingListState(
        shoppingLists: copiedShoppingLists,
        shoppingListItems: copiedShoppingListItems,
      ),
    );
  }

My shoppingListItems state is changing but after rebuild screen.

I use BlocBuilder in my screen

 return BlocBuilder<ShoppingListBloc, ShoppingListState>(
      builder: (context, state) {
        final id = context.read<AppStateBloc>().state.currentShoppingListId;
        List<ShoppingListItem> shoppingListItems = state.shoppingListItems[id]!;
        ShoppingList shoppingList = state.shoppingLists.firstWhere(
          (element) => element.id == id,
        );

i have also tried another way

 void _addItemToShoppingList(
      AddItemToShoppingList event, Emitter<ShoppingListState> emit) async {
    final id = event.shoppingListId;
    ShoppingListItem shoppingListItem = event.shoppingListItem;
    Map<String, List<ShoppingListItem>> shoppingListItems = {
      ...state.shoppingListItems,
      id: state.shoppingListItems[id]!..add(shoppingListItem),
    };
    print(state.toMap());

    emit(
      ShoppingListState(
        shoppingLists: state.shoppingLists,
        shoppingListItems: shoppingListItems,
      ),
    );
    print(state.toMap());
  }

and state printed before and after emit was the same

I hope you can show me where is my mistake

0

There are 0 answers