Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to clear existing records when page parameter changes? #37

Open
arnab opened this issue Jun 28, 2023 · 2 comments
Open

How to clear existing records when page parameter changes? #37

arnab opened this issue Jun 28, 2023 · 2 comments

Comments

@arnab
Copy link

arnab commented Jun 28, 2023

Context

I have the following RiverPagedBuilder:

@override
Widget build(BuildContext context, WidgetRef ref) =>
    RiverPagedBuilder<Page, Item>(
      firstPageKey: Page(
        key: pageKey,
        orderBy: 'publishedAt',
        descending: true,
      ),
      limit: 50,
      provider: paginatedControllerProvider,
      itemBuilder: (context, item, index) => ItemListTile(
        item,
      ),
      pagedBuilder: (controller, builder) => PagedSliverList.separated(
        pagingController: controller,
        builderDelegate: builder,
        separatorBuilder: (ctx, i) => const Divider(
          thickness: 0.8,
          height: 2,
        ),
      ),
    );

And here is the paginatedControllerProvider:

part 'paginated_controller.freezed.dart';

class PaginatedController extends PagedNotifier<Page, Item> {
  final ItemRepository _repository;
  final Logger logger;

  PaginatedController(this._repository, this.logger)
      : super(
          load: (page, limit) {
            logger.i('Fetching next $limit of $page');
            return _repository
                .listItems(
                  itemId: page.itemId,
                  orderBy: page.orderBy,
                  descending: page.descending,
                  lastItem: page.lastItem,
                  limit: limit,
                )
                .first;
          },
          nextPageKeyBuilder: (List<Item>? lastItems, Page page, int limit) =>
              (lastItems == null || lastItems.length < limit)
                  ? null
                  : Page(
                      itemId: page.itemId,
                      orderBy: page.orderBy,
                      descending: page.descending,
                      lastItem: lastItems.last.publishedAt,
                    ),
        );
}

final paginatedControllerProvider = StateNotifierProvider<
    PaginatedController,
    PagedState<Page, Item>>(
  (ref) => PaginatedController(
    ref.read(itemRepositoryProvider),
    ref.read(loggerProvider),
  ),
);

@freezed
class Page with _$Page {
  const Page._();

  const factory Page({
    required String itemId,
    required String orderBy,
    required bool descending,
    @Default(null) dynamic lastItem,
  }) = _Page;
}

Problem

This works great as long as the itemId does not change. When I navigate to a page the first time, it pulls in the expected lastest items (descending order by publishedAt). And then after that, on scrolling it loads the older items, again as expected.

However, when I navigate to a different item page (i.e. itemId is different), it adds the records for this new item to the existing state of records.

I would like to clear the state when the itemId changes. How can I achieve this (or am I not fundamentally using it in a different way)?

@arnab
Copy link
Author

arnab commented Jun 28, 2023

For now, I am detecting in GoRouter's redirect hook if the app is redirecting to the screen in question, and clearing the state of paginated items, if so.

But it does sound like a hack. Please let me know if there is a better way.

@ftognetto
Copy link
Owner

Hi @arnab sorry I've not been using flutter for a long time, are you still interested in a help here?
From what I see maybe a family provider is needed in your case where the family is the itemId

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants