Home > Software design >  Flutter how to migrate this BLoC old version code to Bloc new version
Flutter how to migrate this BLoC old version code to Bloc new version

Time:03-13

how i must write this code in bloc v.8 i don know how i see some searches but im not understand and this is my code for classes they give me error => StateError (Bad state: add(DoFetchEvent) was called without a registered event handler. Make sure to register a handler via on((event, emit) {...})):

 class PostBloc extends Bloc<PostEvent, PostState> {
           PostRepository repo;

        PostBloc(PostState initialState, this.repo) : super(initialState);

      Stream<PostState> mapEventToState(PostEvent event) async* {
           if (event is DoFetchEvent) {
         yield LoadingState();
       try {
      var posts = await repo.fetchPosts();
       yield FetchSuccess(posts: posts);
     } catch (e) {
    yield ErrorState(message: e.toString());
     }
   }
   }
  }

import 'package:equatable/equatable.dart';

 class PostEvent extends Equatable {
 @override
 List<Object?> get props => [];
}

class DoFetchEvent extends PostEvent {}

   class PostState extends Equatable {
       @override
        
      List<Object?> get props => [];
     }

     class InitialState extends PostState {}

     class LoadingState extends PostState {}

       class FetchSuccess extends PostState {
             List<PostModel> posts;

            FetchSuccess({required this.posts});
           }

         class ErrorState extends PostState {
         String message;
      ErrorState({required this.message});
             }

   void main() {
 runApp(MaterialApp(
  home: BlocProvider(
  create: (context) => PostBloc(InitialState(), PostRepository()),
     child: MyApp(),
   ),
 ));
  }

CodePudding user response:

You can set your InitialState directly in the super constructor without manually passing it in like so.

 PostBloc(this.repo) : super(InitialState()) {
    on<DoFetchEvent>(_onDoFetchEvent);
  }

Then you no longer pass in any state in the BlocProvider

 BlocProvider<PostBloc>(
          create: (BuildContext context) => PostBloc(PostRepository()),
...

Then your mapEventToState gets replaced with a method that takes the relevant event, and an Emitter<PostState> as arguments. yield then gets replaced with emit in the method.

Your whole class would look like this.

  PostBloc(this.repo) : super(InitialState()) {
    on<DoFetchEvent>(_onDoFetchEvent);
  }

  _onDoFetchEvent(
    DoFetchEvent event,
    Emitter<PostState> emit,
  ) async {
    emit(LoadingState());
    try {
      var posts = await repo.fetchPosts();
      emit(FetchSuccess(posts: posts));
    } catch (e) {
      emit(ErrorState(message: e.toString()));
    }
  }
}

That should do it.

Besides that, you're probably getting linter warnings about must_be_immutable on your state classes because PostState extend Equatable.

So I suggest making all PostState parameters final and adding the props override from Equatable to your state classes.

class ErrorState extends PostState {
  final String message;
  ErrorState({required this.message});

  @override
  List<Object?> get props => [message];
}
  • Related