Nanda Z
Nanda Z

Reputation: 1886

Inner method in specific state is not recognized, BloC pattern

I build a flutter project by using Bloc State management. But There are something that i don't understand. I know how to make State as Abstract class which it's implement for every it's children. I have class state lake below, please focus to class MainHomeLoaded

abstract class MainHomeState extends Equatable{

  MainHomeState();
}

class MainHomeUnInitialized extends MainHomeState{

  @override
  List<Object> get props => null;

}

class MainHomeLoading extends MainHomeState{

  @override
  List<Object> get props => null;

}

class MainHomeLoaded extends MainHomeState{

  final List<Article> listArticle;
  final bool hasReachedMax;

  MainHomeLoaded({@required this.listArticle, this.hasReachedMax});

  MainHomeLoaded copyWith({
    List<Article> article,
    bool hasReacedMax,
  }){
    return MainHomeLoaded(
      listArticle: article ?? this.listArticle,
        hasReachedMax: hasReacedMax ?? this.hasReachedMax);

  }

  @override
  List<Object> get props => null;

}

class MainHomeError extends MainHomeState{

  final String errorMsg;

  MainHomeError({@required this.errorMsg});

  @override
  List<Object> get props => [errorMsg];

}

then i have MainHomeBloc class with implement Bloc method like mapEventtoState() and inside this method i made conditional like below(again please focus to conditional MainHomeLoaded):

@override
  Stream<MainHomeState> mapEventToState(MainHomeEvent event) async*{

    if(event is CallHomeLatestNews && !_hasReachedMax(state)){

      if(state is MainHomeUnInitialized){

        ResponseArticle responseArticle = await mainHomeRepository.latestNews(event.page);

        if(responseArticle.status == 'success'){
          List<Article> data = responseArticle.data;
          yield MainHomeLoaded(listArticle: data);
        }else{
          yield MainHomeError(errorMsg: responseArticle.message);
        }
      }

      if(state is MainHomeLoaded){

        ResponseArticle responseArticle = await mainHomeRepository.latestNews(event.page);
        if(responseArticle.status == 'success'){
          List<Article> data = responseArticle.data;


          yield data.isEmpty ? state.copyWith(hasReacedMax: true)
              : MainHomeLoaded(listArticle: state.listArticle + data, hasReachedMax: false);

        }
      }
    }

This is part that i don't understand at all, as you can see we have consider that state are in MainHomeLoaded because inside if conditional, but i got error building and my IDE show red line and also method copyWith()doesn't recognize. The error display like this: error pic what IDE says is

method copyWith() is not define for the class 'MainHomeState'

Can someone help me to give simple explanation for this case? Thanks FYI i used Flutter in this version 1.12.13 and Dart version 2.7.0

Upvotes: 2

Views: 727

Answers (1)

Nanda Z
Nanda Z

Reputation: 1886

Finally i found what my main problem. Perhaps it's bit different when we using state in BlocBuilder (in Screens) that automatically known specific state. So what i have to do is just casting it to be child that i wanted. So the solution of this case is like this:

if(state is MainHomeLoaded){

        MainHomeLoaded mainHomeLoaded = state as MainHomeLoaded; // what i need

        ResponseArticle responseArticle = await mainHomeRepository.latestNews(defaultPage);
        if(responseArticle.status == 'success'){

          List<Article> newData = responseArticle.data;


          if(newData.isEmpty){

            mainHomeLoaded.copyWith(hasReacedMax: true);
            yield mainHomeLoaded;
          }
          defaultPage++;
        }else{
          print('gagal');

          yield MainHomeError(errorMsg: responseArticle.message);

        }
      }

i hope it will help someone in future.

Upvotes: 3

Related Questions