flutter- Can I implemment BlocProvider in the app tree instead of implemmented in runApp?

Issue

I’m working in application, that do not use bloc as state management, and I want to add more feature, (the feature will use the bloc), when I try to run the App I got this Error:

══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY
╞═══════════════════════════════════════════════════════════ I/flutter
(17157): The following TransportLoading object was thrown building
TransportPage(dirty, state: I/flutter (17157):
_TransportPageState#daf04): I/flutter (17157): Instance of ‘TransportLoading’

TransportLoading is a state in the bloc.

this is the TransportBloc

class TransportBloc extends Bloc<TransportEvent, TransportState> {
  final StudentCircuitRepository  studentCircuitRepository ;
  TransportBloc({this.studentCircuitRepository}) ;

  @override
  TransportState get initialState => throw TransportLoading();

  @override
  Stream<TransportState> mapEventToState (
    TransportEvent event,
  ) async* {
    // TODO: implement mapEventToState
    List<StudentCircuitModel> student ;
    try{
      if(event is LoadingStudentCircuit){
        student = await studentCircuitRepository.fetchStudentCircuit(event.studentList);
      }
      if(student.length == 0){
        yield TransportEmpty();
      }else{
        yield TransportLoaded(studentCircuit: student);
      }
    }catch (_) {
      yield TransportError();
    }
  }
}

this is page where I try to use TransportBloc

class TransportPageBloc extends StatefulWidget {
  final List<StudentUser> stdUser;
  TransportPageBloc(this.stdUser);
  @override
  _TransportBloxState createState() => _TransportBloxState();
}

class _TransportBloxState extends State<TransportPageBloc> {
  @override
  Widget build(BuildContext context) {
    return BlocProvider<TransportBloc>(
      create: (BuildContext context) => TransportBloc(),
      child: TransportPage(widget.stdUser),
    );
  }
}


class TransportPage extends StatefulWidget {
  final List<StudentUser> student;
  TransportPage(this.student);
  @override
  _TransportPageState createState() => _TransportPageState();
}

class _TransportPageState extends State<TransportPage> {


  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Liste des étudiants'),
      ),
      body:
          BlocBuilder<TransportBloc, TransportState>(bloc: TransportBloc(),builder: (context, state) {
        if (state is TransportLoading) {
          BlocProvider.of<TransportBloc>(context).add(LoadingStudentCircuit(studentList: widget.student));
          return _initialWidget();
        } else if (state is TransportLoaded) {
          return _listStudentCircuit(state.studentCircuit);
        } else if (state is TransportEmpty) {
          return _emptyTransport();
        } else if (state is TransportError) {
          return _errorWidget();
        }
        return null;
      }),
    );
  }
}

Widget _initialWidget() {
  return Center(
    child: CircularProgressIndicator(),
  );
}

Widget _listStudentCircuit(List<StudentCircuitModel> studentCircuit) {
  return ListView.separated(
      itemBuilder: (context, index) {
        return Container(
          child: Text(studentCircuit[index].eleve.name),
        );
      },
      separatorBuilder: (context, index) {
        return Divider(
          height: 5.0,
        );
      },
      itemCount: studentCircuit.length);
}

Widget _emptyTransport(){
  return Center(
    child: Text('Verifier que vous avez des enfant'),
  );
}

Widget _errorWidget(){
  return Center(
    child: Text('this is the error page'),
  );
}

Solution

You’re using throw to set your initial state, and that’s not what throw is for.

Replace this

 @override
  TransportState get initialState => throw TransportLoading();

With this, in your TransportBloc

TransportPageBloc() :  super(TransportLoading());

Answered By – Loren.A

Answer Checked By – Pedro (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published.