How to implement pagination on the custom dropdown item's in flutter

24 Views Asked by At

I have been working on a project where I am calling getProductList API which can have hundreds or thousands on data, I choose to use pagination (infinite_scroll_pagination: ^4.0.0). I tried apply it came up with the code mentioned below. the problem is that my function productsPaginationKey.addPageRequestListener((pageKey) {...}); in the OnInit(). What I want is that only 12 products load when screen is called and then user opens the dropdown and scroll for more that it load more 12 than so on... Please guide me what wrong I am doing and how can I fix the following issue. I am looking for a solution as well a explanation so that I can understand the problem. Thanks.

Controller Class:

class SalesByCustomerController extends GetxController with StateMixin {
  late final PagingController<int, ProductModel> productsPaginationKey;
  late String searchQuery;
  late String sortQuery;

  late final GlobalKey<ScaffoldState> scaffoldKey;

  List<Map<String, dynamic>> allProducts = [];
  late TextEditingController productFilterController;
  List<String> productFilters = ['All'];
  String? productFilter;

  void onProductFilterChange(String? selected) {
    productFilter = selected;
    productFilterController.text = selected!;
  }

  Future<void> getProductList(int pageKey, String filter, String sort) async {
    try {
      List<ProductModel> newItems = await BaseClient.safeApiCall(
        ApiConstants.GET_PRODUCT_LIST,
        RequestType.get,
        headers: await BaseClient.generateHeaders(),
        queryParameters: {
          '\$count': true,
          '\$skip': pageKey * ApiConstants.ITEM_COUNT,
          '\$top': ApiConstants.ITEM_COUNT,
          if (filter.isNotEmpty) '\$filter': filter,
          if (sort.isNotEmpty) '\$orderby': sort,
        },
        onSuccess: (json) {
          List<ProductModel>? products;
          if (json.data['value'] != null) {
            products = [];
            json.data['value'].forEach((v) {
              products?.add(ProductModel.fromJson(v));
            });
          }
          return products ?? [];
        },
        onError: (e) {
          throw Exception('Failed to fetch products');
        },
      );

      final isLastPage = newItems.length < ApiConstants.ITEM_COUNT;
      if (isLastPage) {
        productsPaginationKey.appendLastPage(newItems);
      } else {
        final nextPageKey = pageKey + 1; // Increment page number
        productsPaginationKey.appendPage(newItems, nextPageKey);
      }

      for (ProductModel product in newItems) {
        if (product.productName != null) {
          allProducts.add({'name': product.productName, 'id': product.productId});
          productFilters.add(product.productName!);
        }
      }
    } catch (error) {
      productsPaginationKey.error = error;
    }
  }

  @override
  void onInit() {
    scaffoldKey = GlobalKey<ScaffoldState>();
    searchQuery = "";
    sortQuery = "productName asc";
    productsPaginationKey = PagingController(firstPageKey: 0);
    productsPaginationKey.addPageRequestListener((pageKey) {
      getProductList(pageKey, searchQuery, sortQuery);
    });
    super.onInit();
  }

  @override
  void dispose() {
    productsPaginationKey.dispose();
    super.dispose();
  }
}

View Class:

class SalesByCustomer extends GetView<SalesByCustomerController> {
  static const String routeName = '/salesByCustomer';

  const SalesByCustomer({super.key});

  @override
  Widget build(BuildContext context) {
    return PageTemplate(
      overscroll: false,
      showThemeButton: false,
      showMenuButton: true,
      scaffoldKey: controller.scaffoldKey,
      padding: Sizes.PADDING_12,
      children: [
        ...
        _buildFilterBar().sliverToBoxAdapter,
        ...
      ],
    ).scaffoldWithDrawer();
  }

  Widget _buildFilterBar() {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Row(
          children: [
            ...
            Expanded(
              child: CustomDropDownField<String>(
                  controller: controller.productFilterController,
                  showSearchBox: true,
                  title: 'Product',
                  prefixIcon: Icons.inventory,
                  onChange: controller.onProductFilterChange,
                  items: controller.productFilters,
                  selectedItem: controller.productFilter,
                  verticalPadding: 10,
                ),
            ),
          ],
        ),
      ],
    );
  }
}
0

There are 0 best solutions below