0

hope you're all are doing well and #stayhome and keep #socialdistancing :)

I do have a small problem with the flutter_bloc library and I'm hoping that someone can help me out.

I have an API-Call (moviesStream), which returns a stream. What I would like to have is: on every yield from that stream do a yield in my bloc and therefore rebuild my widget per item and not at the end for all items. I want to build the items successively one after the other

This is my approach and I don't get why it doesn't work. I am very open for any other approach to achieve my goal

What I've learned so far: I cannot yield the same state but my old and new one are different, so that should not be a problem (I think). Do I need to dispatch/add a new Event (or the same again) after yielding? I understand that maybe this would solve my problem, but that would start my stream again from the beginning, wouldn't it?

Stream<FilmeState> mapEventToState(FilmeEvent event) async* {
    final currentState = state;

    yield FilmeStateUninitialized();

    if (event is FilmeEventLoad)
    {
      yield FilmeStateLoadedV2(items: []);

      var moviesStream = Stream.fromIterable([{"1":"1"}, {"2":"2"}, {"3":"3"}]);
      await for (var value in moviesStream) {

        var newItems = List<Map<String, dynamic>>.from((state as FilmeStateLoadedV2).items);
        newItems.add(value);
        print("newItems.length=${newItems.length}");
        yield FilmeStateLoadedV2(items: newItems);
      }
}

The output is the following

I/flutter (12087): state=Instance of 'FilmeStateUninitialized' // this comes from my widget (BlocBuilder)
I/flutter (12087): newItems.length=1
I/flutter (12087): newItems.length=2
I/flutter (12087): newItems.length=3
I/flutter (12087): state=Instance of 'FilmeStateLoadedV2' // this comes from my widget (BlocBuilder)

I was expecting or rather I wish to have the following output

I/flutter (12087): state=Instance of 'FilmeStateUninitialized' // this comes from my widget (BlocBuilder)
I/flutter (12087): newItems.length=1
I/flutter (12087): state=Instance of 'FilmeStateLoadedV2' // this comes from my widget (BlocBuilder)
I/flutter (12087): newItems.length=2
I/flutter (12087): state=Instance of 'FilmeStateLoadedV2' // this comes from my widget (BlocBuilder)
I/flutter (12087): newItems.length=3
I/flutter (12087): state=Instance of 'FilmeStateLoadedV2' // this comes from my widget (BlocBuilder)

1 Answers1

0

I think this is happening because you are using stream which is already filled with data, so it is not tacking time to pass data and because of that you are getting only last value.

If you want to check then add following line before yielding state.

 await Future.delayed(Duration(seconds: 1));
Viren V Varasadiya
  • 25,492
  • 9
  • 45
  • 61
  • @user12018375 i updated my answer. look into it may it helps you, – Viren V Varasadiya Apr 07 '20 at 09:43
  • yeah you're right. now it is "working", but I don't really like delaying something. thank you anyway. in the meantime i've noticed that there is a **BlocListener** in the **flutter_bloc** package, and with this one I was able to track the state changes. event without the delay. maybe there's something elementary wrong with my approach. have to overthink it again – user12018375 Apr 07 '20 at 09:48
  • i was about to suggest you about flutter_bloc, but i did't. If you found it useful accept my answer. "Happy Coding". – Viren V Varasadiya Apr 07 '20 at 09:51
  • what would be your approach for achieving what I want to achieve? I have a stream of data, and I want do build the UI for every item succesively one after the other – user12018375 Apr 07 '20 at 09:52
  • If i have to do such task then i will not use bloc pattern because any event is not going to happen from user side on which basis i have to change list view which i am gonna create using it. instead of if i am getting data from server and it is in stream form then i simple use rxdart or simple streamcontroller and stream to build it. – Viren V Varasadiya Apr 07 '20 at 09:56