First of all thank you for this awesome library, it's awesome!
I'm sorry that I'm posting this here, but I've tried asking many people but I just feel stuck with this issue. Hope you would be able to help.
So I have a simple list that's clickable and goes to DetailScreen, issue I have is when I click back from the DetailScreen, how can I manage this state to save the last list
Bloc
if (event is GetNews && !_hasReachedMax(state)) {
try {
if (currentState is NewsInitial) {
final news = await fetchNews(event.cat, pageNumber);
yield NewsLoaded(news, false);
}
if (currentState is NewsLoaded) {
pageNumber++;
final news = await fetchNews(event.cat, pageNumber);
yield news.isEmpty
? currentState.copyWith(hasReachedMax: true)
: NewsLoaded(currentState.node + news, false);
}
} catch (error) {
print(error);
yield NewsError("Error fetching news" + error);
}
} else if (event is GetDetailedNews) {
try {
final filter = await fetchDetailedNews(event.id);
yield DetailedNewsLoaded(filter);
} catch (error) {
yield NewsError("Couldn't fetch news : $error");
}
}
Attaching the event to the bloc
@override
void initState() {
super.initState();
_postBloc = BlocProvider.of<NewsBloc>(context)
..add(GetNews(widget.cat));
}
BlocBuilder
OnBackPressed I'm just stick in the else since I don't know how to manage the state
return BlocBuilder<NewsBloc, NewsState>(builder: (context, state) {
if (state is NewsLoaded) {
return ListView.builder(
controller: _scrollController,
itemCount: state.hasReachedMax
? state.node.length
: state.node.length + 1,
itemBuilder: (context, index) {
fullList = state.node;
print("list: ${state.node} \nlength: ${state.node
.length} \nindex: $index \n--------------");
return index >= state.node.length ?
BottomLoader() :
listViews(context, state.node[index], index);
});
}
else if (state is NewsError) {
return Center(
child: Container(
child: Text(state.message),
));
}
else {
return Center(child: CircularProgressIndicator(),);
}
});
States
abstract class NewsState extends Equatable {
const NewsState();
@override
List<Object> get props => [];
}
class NewsInitial extends NewsState {
const NewsInitial();
@override
List<Object> get props => [];
}
class NewsLoading extends NewsState {
const NewsLoading();
@override
List<Object> get props => [];
}
class NewsLoaded extends NewsState {
final List<Node> node;
final bool hasReachedMax;
NewsLoaded(this.node, this.hasReachedMax);
NewsLoaded copyWith({List<Node> node, bool hasReachedMax}) {
return NewsLoaded(node ?? this.node, hasReachedMax ?? this.hasReachedMax);
}
@override
List<Object> get props => [node];
}
class DetailedNewsLoaded extends NewsState {
final List<Node> node;
DetailedNewsLoaded(this.node);
@override
List<Object> get props => [node];
}
}
In the detail screen i add the GetDetailScreen event, and this event stays when onBackPressed
@override
void initState() {
BlocProvider.of<NewsBloc>(context)
..add(GetDetailedNews(widget.id));
super.initState();
}
Hope you can help me! Thanks in advance.
Hi @Milansu 馃憢
Thanks for opening an issue and for the positive feedback!
I think the problem is you are yielding NewsLoading in your bloc every time a GetNews event is added/dispatched. Instead, you should only yield NewsLoading if the current state is not NewsLoaded.
// news_bloc.dart
final state = currentState;
if (state is! NewsLoaded) {
yield NewsLoading();
}
...
Let me know if that helps 馃憤
I've tried the WillPopScope before, I had an issue with it, since when I add the event when I press back, it rebuilds the initState where I add the DetailScreen event.
I've tried HydratedBloc but I'm not sure, this only works with initialState?
class NewsBloc extends HydratedBloc<NewsEvent, NewsState> {
@override
NewsState get initialState {
return super.initialState ?? NewsInitial();
}
@override
NewsState fromJson(Map<String, dynamic> json) {
try{
final node = Node.fromJson(json) as List<Node>;
return NewsLoaded(node, false);
}
catch(error) {
return null;
}}
@override
Map<String, dynamic> toJson(NewsState state) {
if(state is NewsLoaded) {
return state.news.toJson(state.node[0]);
}
else {
return null;
}
}
NewsLoading is not making a problem, when I onBackPressed the last state is DetailedNewsLoaded, so my List can't be rebuilt or I can't get its previous state :(
@Milansu are you able to share a link to the code?
I'm sorry I'm not allowed to share it 馃槥
@Milansu can you create a simple sample app which illustrates the issue you're having?
I fixed it by creating a separate bloc, I'm guessing by default each screen should have it's own separate Bloc.
So when I click back I keep my last state (from that screen)
Thank you for help again!
@Milansu not each screen, more like each big enough functionality. 馃槈
@tenhobi Thats it!
Most helpful comment
I fixed it by creating a separate bloc, I'm guessing by default each screen should have it's own separate Bloc.
So when I click back I keep my last state (from that screen)
Thank you for help again!