0

I'm fetching the api data by using http package and flutter-bloc package. I successfully implemented the pagination means when i scroll down at bottom fetch the api by incrementing the page no 1. Now the problem is when i scroll down it returns repeated/ duplicate items on scroll down. Now what i did i debug the http response on scroll down it gives correct data then i checked on models, it also gives correct data. Then when i check on Item.builder it unusually loop/ goback means at starting point when don't scroll the index of an item returns 0 to 3 that is ok. Now when i scroll down the item index should go from 4 to 7 but instead it again goes back from index 0,1 .. index 7. This is what i checked on debugging, Below is the code that on which line i'm doing wrong.

RecommendedForYouPage.dart

class RecommendedForYouPage extends StatefulWidget {
  const RecommendedForYouPage({Key? key}) : super(key: key);
  @override
  _RecommendedForYouPageState createState() => _RecommendedForYouPageState();
}
class _RecommendedForYouPageState extends State<RecommendedForYouPage> {
  late RecommendedViewAllBloc recommendedViewAllBloc;
  late final ScrollController scrollController = ScrollController();
  final List<RecommendedForYouData> recommended = [];
  @override
  void initState() {
    super.initState();
    recommendedViewAllBloc = BlocProvider.of<RecommendedViewAllBloc>(context);
    recommendedViewAllBloc.add(LoadRestaurantRecommendedViewAllEvent());
  }
  @override
  Widget build(BuildContext context) {
    var height = MediaQuery.of(context).size.height;
    var width = MediaQuery.of(context).size.width;
    return Scaffold(
        body: Container(
          transform: Matrix4.translationValues(0, -1, 0),
          color: TuxedoColor.redColor,
          child: Padding(
            padding: const EdgeInsets.only(top: 1.0),
            child: Container(
              decoration: BoxDecoration(
                  color: TuxedoColor.bodyColor,
                  borderRadius: BorderRadius.only(
                    topLeft: Radius.circular(40),
                    topRight: Radius.circular(40),
                  )),
              child: Container(
                child: Padding(
                  padding:
                      const EdgeInsets.only(top: 20.0, left: 20.0, right: 20.0),
                  child: Container(
                    height: height,
                    child: BlocBuilder<RecommendedViewAllBloc,
                        RecommendedViewAllState>(
                      builder: (context, state) {
                        if (state is RecommendedViewAllStateInitial ||
                            state is RecommendedViewAllStateLoading &&
                                recommended.isEmpty) {
                          return Center(child: CircularProgressIndicator());
                        } else if (state is RecommendedViewAllStateSuccess) {
                          recommended.addAll(state.data);
                          BlocProvider.of<RecommendedViewAllBloc>(context)
                              .isFetching = false;
                        } else if (state is RecommendedViewAllStateFailure &&
                            recommended.isEmpty) {
                          return Center(child: Text(state.message));
                        }
                        return ListView.builder(
                          controller: scrollController
                            ..addListener(() {
                              if (scrollController.position.atEdge &&
                                  !BlocProvider.of<RecommendedViewAllBloc>(
                                          context)
                                      .isFetching) {
                                if (scrollController.position.pixels != 0) {
                                  BlocProvider.of<RecommendedViewAllBloc>(
                                      context)
                                    ..isFetching = true
                                    ..add(
                                        LoadRestaurantRecommendedViewAllEvent());
                                }
                              }
                            }),
                          itemBuilder: (context, index) => recommendedListItem(
                            recommended[index], // On this line giving duplicate items
                          ),
                          itemCount: recommended.length,
                          shrinkWrap: true,
                          primary: false,
                          scrollDirection: Axis.vertical,
                        );
                      },
                    ),
                  ),
                ),
              ),
            ),
          ),
        ));
  }

  recommendedListItem(RecommendedForYouData recommended) {
return Container(
height:200.0,
width:200.0,
child:Text(recommended.branchesLocales![0]!.name!,)
)
  }

  @override
  void dispose() {
    scrollController.dispose();
    super.dispose();
  }
}
RecommendedViewAllBloc
class RecommendedViewAllBloc
    extends Bloc<RecommendedViewAllEvent, RecommendedViewAllState> {
  RecommendedForYouDataService dataService;
  int page = 0;
  bool isFetching = false;
  RecommendedViewAllBloc(this.dataService)
      : super(RecommendedViewAllStateInitial());

  @override
  Stream<RecommendedViewAllState> mapEventToState(
    RecommendedViewAllEvent event,
  ) async* {
    yield RecommendedViewAllStateLoading();
    try {
      List<RecommendedForYouData> recommended =
          await dataService.makeRequestRecommendedForYouViewAll(page)
              as List<RecommendedForYouData>;
      yield RecommendedViewAllStateSuccess(recommended);
      page++;
    } catch (e) {
      yield RecommendedViewAllStateFailure(e.toString());
    }
  }
}

RecommendedViewAllEvent

abstract class RecommendedViewAllEvent {}

class LoadRestaurantRecommendedViewAllEvent extends RecommendedViewAllEvent {}

RecommendedViewAllState

abstract class RecommendedViewAllState {}

class RecommendedViewAllStateInitial extends RecommendedViewAllState {}

class RecommendedViewAllStateLoading extends RecommendedViewAllState {}

class RecommendedViewAllStateSuccess extends RecommendedViewAllState {
  final List<RecommendedForYouData> data;

  RecommendedViewAllStateSuccess(this.data);
}

class RecommendedViewAllStateFailure extends RecommendedViewAllState {
  final String message;

  RecommendedViewAllStateFailure(this.message);
}

DataService

class RecommendedForYouDataService {
  Future<List<RecommendedForYouData>?> makeRequestRecommendedForYouViewAll(
      int offset) async {
    Location location = new Location();
    var latitude = "";
    var longitude = "";
    LocationData _locationData;
    _locationData = await location.getLocation();
    latitude = _locationData.latitude.toString();
    longitude = _locationData.longitude.toString();
    var response = await http.get(Uri.parse(
        '$baseURL/restaurant_branches?latitude=$latitude&longitude=$longitude&offset=$offset&limit=4'));
    if (response.statusCode == 200) {
      var data = jsonDecode(response.body);
      List<RecommendedForYouData>? recommendedRestaurant =
          RecommendedForYou.fromJson(data).data as List<RecommendedForYouData>;
      return recommendedRestaurant;
    } else {
      throw Exception();
    }
  }
}
}
Mohammed Nabil
  • 662
  • 1
  • 8
  • 36
  • which items are duplicated ? i mean the first page is duplicated in second page ? – Michael Soliman Sep 21 '21 at 15:56
  • @MichaelSoliman It is same (first) page, when i scroll down i see duplicated items (api data) in ListView builder. – Mohammed Nabil Sep 21 '21 at 16:30
  • you mean the first page is (duplicated + second page data) ? or second page data does not even show up ? – Michael Soliman Sep 21 '21 at 17:34
  • @MichaelSoliman There is only one page, what problem i'm facing is when i scroll down on same page i see duplicate item – Mohammed Nabil Sep 21 '21 at 17:54
  • yes i understand, i just want to know what data is duplicated, because i had i similar problem and it turned out i'm using the same object to pass the data, and in dart (where everything is a reference), this object might have the old data as well as the new! can you add a snippet of dataService code ? – Michael Soliman Sep 21 '21 at 18:15
  • what i mean is `state.data` might have all of the items (the old and the new), and you're adding all of them in `recommended`, so this's maybe why you're having dups – Michael Soliman Sep 21 '21 at 18:17
  • @MichaelSoliman So what is the solution, by the way i have updated the code (added data service). – Mohammed Nabil Sep 21 '21 at 18:21
  • try changing this line `recommended.addAll(state.data);` to this `recommended = state.data` and tell me what you got! – Michael Soliman Sep 21 '21 at 19:41

0 Answers0