Observing streams using Cubit (BLoC library)?
Asked Answered
D

1

11

TL;DR: Is there a way to listen to streams and emit state using Cubit instead of BLoC?

I'm using the BLoC library for Flutter and we use Cubits for our state management. Everything is working all right so far for interactions to get data or save data but now I need to work with streams. In my case that means watching snapshots from FirebaseFirestore.

I tried searching the internet if there are ways to observe streams for Cubit rather than using BLoC but most of the results point me to BLoC. I've worked with BLoC in another project so I know how to use it for observing streams but I wanted to use Cubit instead if there is a way.

Here is an example of the code I use to observe in FireStore:

@override
  Stream<Either<Failure, List<MTalk>>> watchTalk() async* {
    const path ='path/to/talks';
    yield* firestore
        .collection(path)
        .snapshots()
        .map(
          (snap) => right<Failure, List<MTalk>>(
            snap.docs
                .map(
                    (documentSnapshot) => MTalk.fromFirestore(documentSnapshot))
                .toList(),
          ),
        )
        .onErrorReturnWith((e) {
      if (e is FirestoreException) {
        return left(RetrieveFailure(message: e.message));
      } else {
        return left(UnknownFailure(message: e.toString()));
      }
    });
  }
}

When using BLoC, you could simply use async* and yield to return the state whenever you return data from calling watchTalk() because mapEventToState() is also a Stream that yields State. In the case of Cubit, we use emit(MyState) to get state in the UI and the functions aren't of type Stream. What I wanna know is if we can use Cubit to work with streams.

Dorcy answered 2/2, 2021 at 9:20 Comment(1)
Yes, this is described also with examples in the documentation: bloclibrary.dev/#/coreconcepts?id=cubitXylol
D
5

In case anyone gets confused like I did it is pretty straightforward. You can call on listen on your cubit and emit state each time you get a value from the stream. Here's an example of my code listening for changes in network connectivity using DataConnectionChecker:

///Listens to the connectivity of
Future<void> listenToConnectivity() async {
  if (_internetStream != null) {
    await _internetStream.cancel();
  }
  _internetStream = repo.isConnectedToInternet().listen((result) {
    result.fold(
      (failure) => _processFailure(failure: failure),
      (isConnected) {
        if (isConnected) {
          emit(const SessionState.connected());
        } else {
          emit(const SessionState.disconnected());
        }
      },
    );
  });
}
Dorcy answered 28/2, 2021 at 6:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.