Bloc: Regression: initial state is not emited anymore

Created on 23 Jul 2020  ·  2Comments  ·  Source: felangel/bloc

Describe the bug

Initial state isn't emitted on start, as it was on previous versions. Haven't found any change description, why it should doesn't work now. Tested on bloc 6.0.1.

To Reproduce
Given minimal sample (notice "skip: 0"):

import 'package:bloc/bloc.dart';
import 'package:bloc_test/bloc_test.dart';
import 'package:test/test.dart';

abstract class Event {}

class SampleBloc extends Bloc<Event, String> {
  SampleBloc(String initialState) : super(initialState);

  @override
  Stream<String> mapEventToState(Event event) async* {
    yield "b";
  }
}

void main() {
  test('should emit proper states', () async {
    // Given
    final bloc = SampleBloc("a");

    // Then
    await emitsExactly(
      bloc,
      ["a"],
      skip: 0,
    );
  });

  test('should emit proper states', () async {
    // Given
    final bloc = SampleBloc("a");

    // Then
    expect(await bloc.first, "a");
  });
}

Expected behavior
Tests should pass, bloc should emit an initial state.

Logs

should emmit proper states:

ERROR: Expected: ['a']
  Actual: []
   Which: shorter than expected at location [0]

package:test_api                               expect
package:bloc_test/src/emits_exactly.dart 65:3  emitsExactly
duplicate question

Most helpful comment

This is a quick fix for those who also lack this feature. Add BehaviorSubjectBloc mixin to your Bloc class:

class CounterBloc extends Bloc<int, int> with BehaviorSubjectBloc {
  ...
}

mixin BehaviorSubjectBloc<TEvent, TState> on Bloc<TEvent, TState> {
  @override
  StreamSubscription<TState> listen(void Function(TState state) onData,
      {Function onError, void Function() onDone, bool cancelOnError}) {
    onData(this.state);
    return super.listen(onData,
        onError: onError, onDone: onDone, cancelOnError: cancelOnError);
  }
}

All 2 comments

Hi @marcin-jelenski 👋
Thanks for opening an issue!

This isn’t a regression and was an intentional breaking change that is documented in the changelog as well as in the migration guide.

This is also a duplicate of #1512.

You can test your initial state via:

test(‘initial state is correct’, () {
  expect(SampleBloc(‘a’).state, ‘a’);
});

Sorry for any inconvenience!
Closing for now but feel free to comment with additional questions/concerns and I’m happy to continue the conversation 👍

This is a quick fix for those who also lack this feature. Add BehaviorSubjectBloc mixin to your Bloc class:

class CounterBloc extends Bloc<int, int> with BehaviorSubjectBloc {
  ...
}

mixin BehaviorSubjectBloc<TEvent, TState> on Bloc<TEvent, TState> {
  @override
  StreamSubscription<TState> listen(void Function(TState state) onData,
      {Function onError, void Function() onDone, bool cancelOnError}) {
    onData(this.state);
    return super.listen(onData,
        onError: onError, onDone: onDone, cancelOnError: cancelOnError);
  }
}
Was this page helpful?
0 / 5 - 0 ratings

Related issues

1AlexFix1 picture 1AlexFix1  ·  3Comments

clicksocial picture clicksocial  ·  3Comments

RobPFarley picture RobPFarley  ·  3Comments

abinvp picture abinvp  ·  3Comments

MahdiPishguy picture MahdiPishguy  ·  3Comments