Hi, Felix! Using flutter_bloc on current project and enjoying it so far.
But I encountered one issue multiple times , let me show simple example:
We've got two states:
// show data on a screen
class DataLoaded extends SomeBlocState {
DataLoaded([this.data]) : super(<dynamic>[data]);
final dynamic data;
@override
String toString() => 'DataLoaded';
}
// show a circular progress
class IsFetching extends SomeBlocState {
@override
String toString() => 'IsFetching';
}
The case - when current state is DataLoaded and it is shown on a screen, then user triggers fetching new data, state changes on IsFetching and here I need to still show old data and circular progress simultaneously. And only after successful fetching show new data. Requests could be triggered from multiple places even from different widget tree, so calling setState() { _loading = true; bloc.dispatch(RequestData());} and then to turn it off at a BlocListener on DataLoaded isn't the case for me.
One more example - to show dialog at BlocListener reacting on a new state, or navigate to login page if server returns 401 and still show old data.
In real project I've got many times more this kind of situations.
How do I achieve this? Or may be I'm doing something in a wrong way.
Thanks in advance.
Hi @intako 馃憢
Thanks for opening an issue!
If you need to share data across multiple states then you can just have a base class that holds the data and extend the base class for each of your bloc states.
class Populated extends SomeBlocState {
DataLoaded([this.data]) : super(<dynamic>[data]);
final dynamic data;
}
class DataLoaded extends Populated {
DataLoaded([dynamic data]) : super(data);
@override
String toString() => 'DataLoaded';
}
class IsFetching extends Populated {
IsFetching([dynamic data]) : super(data);
@override
String toString() => 'IsFetching';
}
In this case both DataLoaded and IsFetching are Populated states because they both contain data.
Hope that helps! 馃憤
Thanks a lot for the quick reply!
It might help, but in this case we'd have to pass data as argument on every state change, so now we have two states. But what if there are more states, some states for just BlocListener as well.
And if the DataLoaded state contains not only data field, but another two fields then we'd have to share them across all states and it's a question of time when it'll become hard to maintain.
What would you suggest in this case?
@intako no problem! In that case, if a single state will always need multiple properties (data and isLoading) you can simply combine the properties into a single state and implement a copyWith.
You can check out the infinite list tutorial for an example.
Got it! Thank you very much for your help, Felix!
Most helpful comment
Got it! Thank you very much for your help, Felix!