It is so weird that it only happens on this specific page. In the blocConsumer, listener receives the state with EditProjectLoading status and GeneratePdfFailed status correctly, but for builder it only receives state with EditProjectLoading status. Really need some help on this.
class TabEditProjectState extends Equatable {
final Status status;
final Project project;
TabEditProjectState({this.status = const EditProjectInitial(), this.project});
TabEditProjectState copyWith({Status status, Project project, String path}) {
return TabEditProjectState(
status: status ?? this.status,
project: project ?? this.project
);
}
@override
List<Object> get props => [status, project];
}
Future<void> doSomeWork() async {
emit(state.copyWith(status: const EditProjectLoading()));
emit(state.copyWith(status: GeneratePdfFailed(ex.toString())));
}
class SomeWidget {
@override
Widget build(BuildContext context) {
return BlocConsumer<T, S>(
listener: (BuildContext context, state) {
widget.blocListener(context, state);
},
builder: (BuildContext context, state) {
return LoadingLayout(showLoading: showLoading, child: widget.child);
},
);
}
}
Remove equatable in state class it will work
@venkateshironman appreciate your input, but how does cubit compare without equatable?
@PandaGeek1024 Equatable it is just a shorcut to avoid implementing hashCode and the == operator. So, under the hood, it is using this methods (you can check the implementation in the Equatable package repository).
It still compares it with the mentioned methods.
Remove equatable in state class it will work
it does not work
Do you use the BlocObserver?
With it, you could check if the event is sent. From there, if onEvent function from the observer does not print anything, I would mean you are not sending the new state properly. If it does but nothing shows up in the onTransition function, it is due to minor logic with the state.
Check that all custom classes used in it extend Equatable or they have implemented hashCode and == by value (since Dart equality works by reference).
If the problem persists, upload a bit more of code so we can dig deeper 馃槂
can i send the same state f.e. emit(state..network=Network.LOADED)?
And override listenWhen and/or buildWhen property on BlocListener,BlocConsumer, BlocBuilder
f.e BlocListener( listener:(context,state){
if (state.network == NetworkState.LOADED) {
showAlert();
}else{
if(Navigatgor.of(context,rootNavigator:true).canPop()){
Navigatgor.of(context,rootNavigator:true).pop();
}
}
}
listenWhen:(p,c)=>p.network!=c.network,
child:SomeChild()
);
@mikededo does it mean I have to implement my own one after remove equatable?
Remove equatable in state class it will work
It does not work for me either
can i send the same state f.e. emit(state..network=Network.LOADED)?
I cannot see what you are asking for, could you explain a bit more?
does it mean I have to implement my own one after remove equatable?
It depends. If you are using custom classes and you do not want to use Equatable, then yes. For example, let's say you have the nested classes, you have to extend Equatable in all the classes:
class A extends Equatable {
...
@override
List<Object> get props => [];
}
class B extends Equatable {
final A aInstance;
...
@override
List<Object> get props => [aInstance];
}
class C extends Equatable {
final B bInstance;
...
@override
List<Object> get props => [bInstance];
}
/// And so on
So, when comparinc two C instances, it will go use the equatable from C, which involves B, which involves A.
Hope this helps!
Hi @PandaGeek1024 馃憢
Thanks for opening an issue!
Are you still experiencing issues or can this issue be closed? If you're still experiencing issues can you please share a link to a complete sample app which illustrates the problem? Thanks 馃憤
@felangel I have tried created a new project and copy all the code over and problem still exist. But when I create a sample project, I don't see the problem. It is so confusing. I guess in my actual project, the view hierarchy is too complex that cause issue. I have spend 3 days on it and decided to switched to another solution, really don't want to spend time on it anymore.
Well, I feel bad that you did not come with a solution 馃槥
However, most of the problems that happend when the state is not updating or similar, are due to having classes not implementing Equatable (or hashCode and ==) so that Dart does evaluate by reference but by value.
Similar with collections (List, Map and so on), whenever you are creating a new state with a collection from the state, you have to create a new collection with the .for constructor (the constructor .of works aswell). This is because you have to create a new instance of that collection, otherwise, it will point to that state collection and when comparing states, it would return true, since both states point to the same list
@PandaGeek1024 I'm sorry to hear that 馃槥 but as @mikededo mentioned it's usually an equality comparison issue. I'll close this for now if you don't want to spend more time on it but feel free to comment with additional questions/info and I'm happy to continue the conversation 馃憤
Remove equatable in state class it will work
thanks it works for me !
1 day struggling to find out why state not emitted in the second time coming with same result, when i remove equatable finally state can emitted in many time
@ubaidillahSriyudi thats glad to hear
Most helpful comment
Remove equatable in state class it will work