Prime-Holding / rx_bloc

A set of Flutter packages that help implement the BloC (Business Logic Component) design pattern using the power of reactive streams
https://pub.dev/packages/rx_bloc
62 stars 21 forks source link

Help with updating a single state with more than 2 events #722

Closed bensonarafat closed 3 months ago

bensonarafat commented 3 months ago

Hi @StanevPrime I am current facing an issue, i cant find anywhere in the example that explain this.

I have a state called myFriends

I can perform various event to update this state like search, sort, paginate,

But how can i use these events to update just this state.

Here is how my current code work for just fetch and paginate

// event
abstract class TasteBudsBlocEvents {

  void searchMyFriends({String? query});

  void fetchPaginatedMyFriends({bool? refresh});

  void applySort({SortingOption? option});
}

// state 
abstract class TasteBudsBlocStates {
  Stream<bool> get isLoading;

  Stream<String> get errors;

  Stream<Result<List<MyItems>>> get myItems;

  Stream<int> get selectedIndex;

  Stream<SortingOption> get selectedSort;

  Stream<User> get currentUser;

  Stream<bool> get hasMoreData;
}

@RxBloc()
class FriendsBloc extends $FriendsBloc {
 final AuthRepository _authRepository;
  final UserRepository _userRepository;

  final _hasMoreData = BehaviorSubject<bool?>();
  final _lastDocument = BehaviorSubject<DocumentSnapshot?>();

  final _myFriendsList = BehaviorSubject<List<User>>.seeded([]);

  FriendsBloc(this._authRepository, this._userRepository) {
    _bindEvents();
  }

  void _bindEvents() {

    _$fetchPaginatedMyBudsEvent
        .withLatestFrom2(
            _authRepository.currentUser, _hasMoreData.startWith(null),
            (bool? refresh, User? user, bool? hasMoreData) {
          if (refresh == true) {
            _lastDocument.add(null);
            _myBudsList.add([]);
            return user;
          }
          return hasMoreData == false ? null : user;
        })
        .whereNotNull()
        .switchMap((user) {
          print("Search");
          return _userRepository.getInvitationsList(
              InvitationStatus.accepted, user,
              limit: Constants.itemsPerPage,
              lastDoc: _lastDocument.valueOrNull,
              paginated: true);
        })
        .listen((users) {
          bool hasMoreData = users.length == Constants.itemsPerPage;
          _hasMoreData.add(hasMoreData);
          _lastDocument.add(hasMoreData ? users.last.documentSnapshot : null);
          _myFriendsList.add([..._myFriendsList.value, ...users]);
        });

  }

  @override
  Stream<Result<List<User>>> _mapToMyFriendsState() =>
      _myFriendsList.map(Result.success).share();

  @override
  Stream<SortingOption> _mapToSelectedSortState() => _$applySortEvent
      .startWith(SortingOption.alphabetically)
      .map((event) => event ?? SortingOption.alphabetically);
}

I could use Rx.merge() but fetchPaginatedMyFriends could be bool and searchMyFriends will be string

Please how can i put all this into account. thanks

StanevPrime commented 3 months ago

I believe you can found the same challenge into the github_search sample application, and more specifically the DashboardBloc

A couple of hints from my side

Let me know if this helps or you need further assistance from my side

bensonarafat commented 3 months ago

Thanks, Just resolved it.