Search code examples
streamdartflutter

Flutter : stream two Streams into a single screen?


I have two streams fetching from two different api.

Stream<Month> get monthOutStream => monthOutController.stream;
Stream<MySchedule> get resultOutStream => resultController.stream;

I am fetching these data at two different state of the application, result at the begining and Months after some events from user.

MyScheduleBloc(){
  initialData();
}

Future initialData() async {
  MySchedule mySchedule = await myScheduleViewModel.importMySchedule(now.id);
  resultController.add(mySchedule);
}

My screen has a streambuilder as

Widget build(BuildContext context) {
final webCalenderBloc = WebCalenderBloc();
return StreamBuilder(
  stream: webCalenderBloc.resultOutStream,
  builder: (BuildContext context , snapdata){
    if(!snapdata.hasData){
      return Center(
        child: CircularProgressIndicator(),
      );
    }
    return body(snapdata.data);
   },
 );
}

Since the main widget build method took the StreamBuilder Widget with resultoutstream as a stream.Where do i fetch the other stream monthoutStream. Can i fetch stream inside a stream? Do i missing anything while handling two stream.I dont want to build any widget from monthoutstream but want to check the data inside it.


Solution

  • You can nest StreamBuilder if needed. Nothing prevents you from doing the following:

    StreamBuilder(
      stream: stream1,
      builder: (context, snapshot1) {
        return StreamBuilder(
          stream: stream2,
          builder: (context, snapshot2) {
            // do some stuff with both streams here
          },
        );
      },
    )
    

    Another solution if this makes sense for you is: Streams are designed to be mergeable/transformed. You could make a third stream that is a merge of the two later streams.

    Ideally for complex stream operations you'll want to use rxdart as it provides a few useful transformer.

    Using rxdart, the fusion of two Observable (which are subclass of Stream) would be the following:

    Observable<bool> stream1;
    Observable<String> stream2;
    
    final fusion = stream1.withLatestFrom(stream2, (foo, bar) {
      return MyClass(foo: foo, bar: bar);
    });