Référence de l'API

Requête infinie

Référence complète de InfiniteData, InfiniteQueryState, InfiniteQueryOptions, InfiniteQueryObserver, InfiniteQueryBuilder, InfiniteQueryController et les méthodes de requête infinie de QoraClient.

InfiniteData<TData, TPageParam>

Conteneur immuable contenant toutes les pages récupérées et leurs paramètres de page correspondants.

TData est le type d'une seule page (ex. List<Post>). TPageParam est le type du paramètre de page (ex. int, String?).

pages et pageParams ont toujours la même longueur : pages[i] a été récupéré en utilisant pageParams[i].

Constructeur

const InfiniteData({
  required List<TData> pages,
  required List<TPageParam> pageParams,
})

Vérifie que pages.length == pageParams.length.

Propriétés

Méthodes

flatten

List<TItem> flatten<TItem>(Iterable<TItem> Function(TData page) selector)

Aplatit toutes les pages en une seule liste : la façon canonique de convertir les données paginées pour ListView.builder.

// TData == List<Post>
final posts = data.flatten((page) => page);

// TData est un objet de réponse avec une liste imbriquée
final posts = data.flatten((page) => page.items);

append

InfiniteData<TData, TPageParam> append(TData page, TPageParam param)

Retourne un nouvel InfiniteData avec page et param ajoutés à la fin. Utilisé en interne par fetchNextPage.

prepend

InfiniteData<TData, TPageParam> prepend(TData page, TPageParam param)

Retourne un nouvel InfiniteData avec page et param ajoutés au début. Utilisé en interne par fetchPreviousPage.

dropFirst

InfiniteData<TData, TPageParam> dropFirst()

Retourne un nouvel InfiniteData sans sa première page. Appelé lors du paging fenêtré quand maxPages est dépassé après un fetchNextPage.

dropLast

InfiniteData<TData, TPageParam> dropLast()

Retourne un nouvel InfiniteData sans sa dernière page. Appelé lors du paging fenêtré quand maxPages est dépassé après un fetchPreviousPage.


InfiniteQueryState<TData, TPageParam>

Machine à états de classe sealed pour une requête infinie. Pattern matching exhaustif avec switch :

switch (state) {
  case InfiniteInitial() || InfiniteLoading():
    return const CircularProgressIndicator();
  case InfiniteSuccess(:final data, :final hasNextPage, :final isFetchingNextPage):
    return PostFeed(
      items: data.flatten((page) => page),
      hasMore: hasNextPage,
      loadingMore: isFetchingNextPage,
    );
  case InfiniteFailure(:final error, :final previousData):
    if (previousData != null) {
      return Column(children: [
        PostFeed(items: previousData.flatten((p) => p)),
        ErrorBanner(error),
      ]);
    }
    return ErrorScreen(error);
}

InfiniteInitial

final class InfiniteInitial<TData, TPageParam> extends InfiniteQueryState<TData, TPageParam>

La requête n'a pas encore été exécutée. État par défaut quand aucun fetch n'a été déclenché.


InfiniteLoading

final class InfiniteLoading<TData, TPageParam> extends InfiniteQueryState<TData, TPageParam>

Le fetch de la première page est en cours. Aucune page n'a encore été chargée.

Après le chargement de la première page, l'état ne revient jamais à InfiniteLoading. Les fetches de pages suivantes signalent leur progression via isFetchingNextPage/isFetchingPreviousPage sur InfiniteSuccess, gardant les pages existantes visibles.


InfiniteSuccess

final class InfiniteSuccess<TData, TPageParam> extends InfiniteQueryState<TData, TPageParam>

Toutes les pages actuellement chargées, avec les indicateurs de statut de pagination.

Propriétés

PropriétéTypeDescription
dataInfiniteData<TData, TPageParam>Toutes les pages chargées et leurs paramètres de page.
hasNextPagebooltrue quand getNextPageParam retourne non-null pour la dernière page.
hasPreviousPagebooltrue quand getPreviousPageParam retourne non-null pour la première page. Toujours false si pas de getPreviousPageParam.
updatedAtDateTimeQuand cet état a été mis à jour avec succès pour la dernière fois.
isFetchingNextPagebooltrue pendant un fetch de page suivante. Afficher un indicateur de chargement en bas ; data reste valide.
isFetchingPreviousPagebooltrue pendant un fetch de page précédente. Afficher un indicateur de chargement en haut ; data reste valide.

copyWith

InfiniteSuccess<TData, TPageParam> copyWith({
  InfiniteData<TData, TPageParam>? data,
  bool? isFetchingNextPage,
  bool? isFetchingPreviousPage,
  bool? hasNextPage,
  bool? hasPreviousPage,
  DateTime? updatedAt,
})

Retourne une copie avec les champs spécifiés remplacés. Les champs non spécifiés conservent leurs valeurs actuelles.


InfiniteFailure

final class InfiniteFailure<TData, TPageParam> extends InfiniteQueryState<TData, TPageParam>

Un échec de fetch, avec previousData optionnel pour la dégradation gracieuse.

Propriétés

PropriétéTypeDescription
errorObjectL'erreur levée par la fonction de fetch (après tous les retries).
stackTraceStackTrace?Stack trace optionnelle.
previousDataInfiniteData<TData, TPageParam>?Dernières pages chargées avec succès, le cas échéant. Non-null quand l'échec survient après le chargement de pages.

Quand previousData est non-null, afficher le contenu existant à côté d'un indicateur d'erreur plutôt que de remplacer toute la vue.


InfiniteQueryOptions<TData, TPageParam>

Configuration pour une requête infinie. Combine les QoraOptions standard avec des paramètres spécifiques à la pagination.

Constructeur

const InfiniteQueryOptions({
  required TPageParam initialPageParam,
  required TPageParam? Function(TData lastPage, List<TData> allPages) getNextPageParam,
  TPageParam? Function(TData firstPage, List<TData> allPages)? getPreviousPageParam,
  int? maxPages,
  QoraOptions baseOptions = const QoraOptions(),
})

Vérifie maxPages == null || maxPages >= 1.

Propriétés

PropriétéTypeRequisDescription
initialPageParamTPageParamOuiParamètre pour la toute première page (ex. 1, 0, null ou '').
getNextPageParamTPageParam? Function(TData lastPage, List<TData> allPages)OuiRetourne le paramètre de la prochaine page, ou null quand il n'y a plus de pages (définit hasNextPage à false).
getPreviousPageParamTPageParam? Function(TData firstPage, List<TData> allPages)?NonRetourne le paramètre de la page précédente. Nécessaire uniquement pour le scroll bidirectionnel. Quand null, hasPreviousPage est toujours false.
maxPagesint?NonPages maximum gardées en mémoire. Quand dépassé, la page la plus ancienne est supprimée à fetchNextPage (ou la plus récente à fetchPreviousPage). Doit être >= 1.
baseOptionsQoraOptionsNonOptions standard de retry, stale time, cache time et network mode appliquées à chaque fetch de page. Fusionnées par-dessus QoraClientConfig.defaultOptions.

InfiniteQueryObserver<TData, TPageParam>

Le moteur de pagination central. Gère le cycle de vie complet d'une seule requête infinie : récupération des pages, émission des transitions d'état et respect des gardes de concurrence.

Typiquement créé dans State.initState d'un widget Flutter et disposé dans State.dispose. Pour un binding Flutter prêt à l'emploi, utiliser InfiniteQueryBuilder à la place.

Plusieurs observateurs partageant la même key sur le même client partagent la même entrée de cache sous-jacente, de sorte que tous les listeners reçoivent les mêmes transitions d'état en synchronie.

Constructeur

InfiniteQueryObserver({
  required QoraClient client,
  required Object key,
  required InfiniteQueryFunction<TData, TPageParam> fetcher,
  required InfiniteQueryOptions<TData, TPageParam> options,
})

Propriétés

PropriétéTypeDescription
streamStream<InfiniteQueryState<TData, TPageParam>>Émet l'état actuel immédiatement, puis toutes les futures transitions.
stateInfiniteQueryState<TData, TPageParam>Snapshot synchrone de l'état actuel.

Méthodes

fetch

Future<void> fetch()

Récupère la première page. Sans effet quand :

  • Des données sont déjà chargées (l'état n'est pas InfiniteInitial).
  • Un fetch initial est déjà en cours.

Transitions : InfiniteInitial → InfiniteLoading → InfiniteSuccess | InfiniteFailure.


fetchNextPage

Future<void> fetchNextPage()

Récupère la page suivante et l'ajoute. Sans effet quand :

  • Aucune donnée n'a encore été chargée (appeler fetch d'abord).
  • hasNextPage est false.
  • Un fetch de page suivante ou précédente est déjà en cours.

Pendant le fetch, définit isFetchingNextPage: true sur l'InfiniteSuccess actuel : les pages existantes restent visibles. En cas d'échec, transite vers InfiniteFailure avec previousData renseigné.


fetchPreviousPage

Future<void> fetchPreviousPage()

Récupère la page précédente et la prépend. Sans effet quand :

  • getPreviousPageParam n'est pas configuré.
  • hasPreviousPage est false.
  • Un fetch est déjà en cours.

Pendant le fetch, définit isFetchingPreviousPage: true. En cas d'échec, transite vers InfiniteFailure avec previousData.


refetch

Future<void> refetch()

Re-récupère toutes les pages actuellement chargées en séquence, en préservant le nombre de pages. Utilise les pageParams originaux stockés dans InfiniteData. Utile après client.invalidateInfiniteQuery(key) ou un pull-to-refresh.

  • Si aucune donnée n'est chargée, délègue à fetch().
  • Signale la progression via isFetchingNextPage: true sur l'InfiniteSuccess actuel.
  • En cas d'échec, transite vers InfiniteFailure avec previousData.

dispose

void dispose()

Libère cet observateur. Après le dispose, tous les appels de méthodes ultérieurs sont ignorés silencieusement. L'entrée de cache sous-jacente n'est pas supprimée : les autres observateurs partageant la même clé continuent de fonctionner normalement.


Garanties de concurrence

Tous les gardes (_isFetchingInitial, _isFetchingNext, _isFetchingPrevious, _isRefetching) sont définis comme première instruction synchrone dans leur méthode : avant tout await. Cela prévient les conditions de course dues aux événements de scroll rapide ou aux interactions UI même avant le premier aller-retour réseau.


InfiniteQueryBuilder<TData, TPageParam>

Widget Flutter qui lie une requête infinie à l'arbre de widgets. Voir le guide InfiniteQueryBuilder pour des exemples d'utilisation.

Constructeur

const InfiniteQueryBuilder({
  Key? key,
  required Object queryKey,
  required InfiniteQueryFunction<TData, TPageParam> fetcher,
  required InfiniteQueryOptions<TData, TPageParam> options,
  required Widget Function(
    BuildContext context,
    InfiniteQueryState<TData, TPageParam> state,
    InfiniteQueryController<TData, TPageParam> controller,
  ) builder,
  QoraClient? client,
  bool enabled = true,
})

Props

PropTypeDéfautDescription
queryKeyObject (List ou QoraKey)requisClé de cache. La changer dispose l'observateur actuel et repart de initialPageParam.
fetcherInfiniteQueryFunction<TData, TPageParam>requisFuture<TData> Function(TPageParam pageParam) : récupère une seule page.
optionsInfiniteQueryOptions<TData, TPageParam>requisConfiguration de pagination.
builderWidget Function(BuildContext, InfiniteQueryState, InfiniteQueryController)requisConstruit l'arbre de widgets depuis l'état et le contrôleur.
clientQoraClient?nullRemplace le QoraClient depuis QoraScope. Utile pour les tests.
enabledbooltrueQuand false, le fetch de la première page est supprimé. Le widget observe toujours l'état en cache actuel.

InfiniteQueryController<TData, TPageParam>

Interface stable exposant les actions de pagination au callback InfiniteQueryBuilder.builder. La référence du contrôleur est stable tant que queryKey et client restent inchangés.

Méthodes

MéthodeSignatureDescription
fetchNextPage()Future<void>Récupère et ajoute la page suivante. Sans effet si hasNextPage est false ou un fetch est en cours.
fetchPreviousPage()Future<void>Récupère et prépend la page précédente. Nécessite getPreviousPageParam configuré.
refetch()Future<void>Re-récupère toutes les pages chargées en séquence. Utile pour le pull-to-refresh (onRefresh: controller.refetch).

InfiniteQueryFunction<TData, TPageParam>

typedef InfiniteQueryFunction<TData, TPageParam> = Future<TData> Function(
  TPageParam pageParam,
);

Le type du paramètre fetcher sur InfiniteQueryObserver et InfiniteQueryBuilder. Reçoit le paramètre de page calculé par getNextPageParam/getPreviousPageParam et retourne un Future résolvant en une seule page de données.


QoraClient : Méthodes de requête infinie

watchInfiniteState

Stream<InfiniteQueryState<TData, TPageParam>> watchInfiniteState<TData, TPageParam>(Object key)

Retourne un stream broadcast qui émet immédiatement l'InfiniteQueryState actuel pour key, puis émet toutes les futures transitions. S'abonner empêche le GC de l'entrée de cache.


getInfiniteQueryState

InfiniteQueryState<TData, TPageParam> getInfiniteQueryState<TData, TPageParam>(Object key)

Snapshot synchrone de l'état actuel. Retourne InfiniteInitial() si aucune entrée n'existe en cache.


getInfiniteQueryData

InfiniteData<TData, TPageParam>? getInfiniteQueryData<TData, TPageParam>(Object key)

Retourne l'InfiniteData de l'état InfiniteSuccess actuel, ou null si l'état n'est pas InfiniteSuccess.

posts_screen.dart
final snapshot = client.getInfiniteQueryData<List<Post>, int>(['posts']);

setInfiniteQueryData

void setInfiniteQueryData<TData, TPageParam>(
  Object key,
  InfiniteData<TData, TPageParam> data, {
  bool? hasNextPage,
  bool? hasPreviousPage,
})

Injecte directement InfiniteData dans le cache, poussant un état InfiniteSuccess vers tous les abonnés actifs. Utiliser pour les mises à jour optimistes.

posts_screen.dart
// Prépendre optimistement un nouveau post à la page 1
final snapshot = client.getInfiniteQueryData<List<Post>, int>(['posts']);
if (snapshot != null) {
  client.setInfiniteQueryData(
    ['posts'],
    InfiniteData(
      pages: [
        [Post.optimistic(title), ...snapshot.pages.first],
        ...snapshot.pages.skip(1),
      ],
      pageParams: snapshot.pageParams,
    ),
  );
}

try {
  await api.createPost(title);
  client.invalidateInfiniteQuery(['posts']);
} catch (_) {
  if (snapshot != null) client.setInfiniteQueryData(['posts'], snapshot);
}

updateInfiniteQueryState

void updateInfiniteQueryState<TData, TPageParam>(
  Object key,
  InfiniteQueryState<TData, TPageParam> state,
)

Le chemin d'écriture brut pour n'importe quel InfiniteQueryState. Utilisé en interne par InfiniteQueryObserver. Préférer setInfiniteQueryData pour les mises à jour uniquement des données.


invalidateInfiniteQuery

void invalidateInfiniteQuery(Object key)

Réinitialise l'entrée de cache pour key à InfiniteInitial. Les instances InfiniteQueryBuilder actives détectent la réinitialisation et re-récupèrent automatiquement la première page, de sorte que l'UI ne reste jamais vide.

anywhere.dart
await api.createPost(title);
client.invalidateInfiniteQuery(['posts']);

Voir aussi

Copyright © 2026