From afa9933c9109b3ace49807af6a025115e197de80 Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Tue, 5 Jul 2022 09:28:43 +0600 Subject: [PATCH] refetch on external data change support added --- .../lib/components/query_external_data.dart | 1 + .../fl_query/lib/src/hooks/use_query.dart | 22 +++++++++++++------ .../fl_query/lib/src/models/query_job.dart | 4 ++++ packages/fl_query/lib/src/query_bowl.dart | 12 ++++++++++ packages/fl_query/lib/src/query_builder.dart | 21 ++++++++++++------ 5 files changed, 46 insertions(+), 14 deletions(-) diff --git a/packages/example/lib/components/query_external_data.dart b/packages/example/lib/components/query_external_data.dart index 6b58090..a433d71 100644 --- a/packages/example/lib/components/query_external_data.dart +++ b/packages/example/lib/components/query_external_data.dart @@ -6,6 +6,7 @@ import 'package:flutter/material.dart'; final jobWithExternalData = QueryJob( queryKey: "query-external-data", cacheTime: const Duration(seconds: 10), + refetchOnExternalDataChange: false, task: (queryKey, data) { return Future.delayed(const Duration(milliseconds: 500), () => "Hello from $queryKey with $data"); diff --git a/packages/fl_query/lib/src/hooks/use_query.dart b/packages/fl_query/lib/src/hooks/use_query.dart index c85c42f..0687bf5 100644 --- a/packages/fl_query/lib/src/hooks/use_query.dart +++ b/packages/fl_query/lib/src/hooks/use_query.dart @@ -75,13 +75,21 @@ Query useQuery({ } else if (oldExternalData != null && externalData != null && !isShallowEqual(oldExternalData, externalData)) { - QueryBowl.of(context).fetchQuery( - job, - externalData: externalData, - onData: onData, - onError: onError, - key: uKey, - ); + if (job.refetchOnExternalDataChange ?? + queryBowl.refetchOnExternalDataChange) { + QueryBowl.of(context).fetchQuery( + job, + externalData: externalData, + onData: onData, + onError: onError, + key: uKey, + ); + } else { + QueryBowl.of(context) + .getQuery(job.queryKey) + ?.setExternalData(externalData); + } + if (hasOnDataChanged) query.value.onDataListeners.remove(oldOnData); if (hasOnErrorChanged) query.value.onErrorListeners.remove(oldOnError); } else { diff --git a/packages/fl_query/lib/src/models/query_job.dart b/packages/fl_query/lib/src/models/query_job.dart index f3462b6..677dbe0 100644 --- a/packages/fl_query/lib/src/models/query_job.dart +++ b/packages/fl_query/lib/src/models/query_job.dart @@ -32,6 +32,7 @@ class QueryJob { // got from global options bool? refetchOnMount; bool? refetchOnReconnect; + bool? refetchOnExternalDataChange; Duration? staleTime; Duration? cacheTime; @@ -49,6 +50,7 @@ class QueryJob { this.refetchInterval, this.refetchOnMount, this.refetchOnReconnect, + this.refetchOnExternalDataChange, }) : _queryKey = queryKey; String get queryKey => _queryKey; @@ -70,6 +72,7 @@ class QueryJob { Duration? refetchInterval, bool? refetchOnMount, bool? refetchOnReconnect, + bool? refetchOnExternalDataChange, }) { return (String queryKey) { if (preQueryKey != null) queryKey = "$preQueryKey#$queryKey"; @@ -85,6 +88,7 @@ class QueryJob { refetchInterval: refetchInterval, refetchOnMount: refetchOnMount, refetchOnReconnect: refetchOnReconnect, + refetchOnExternalDataChange: refetchOnExternalDataChange, ); }; } diff --git a/packages/fl_query/lib/src/query_bowl.dart b/packages/fl_query/lib/src/query_bowl.dart index aadde65..fbe6d29 100644 --- a/packages/fl_query/lib/src/query_bowl.dart +++ b/packages/fl_query/lib/src/query_bowl.dart @@ -60,6 +60,13 @@ class QueryBowlScope extends StatefulWidget { /// off by passing [Duration.zero] final Duration refetchOnReconnectDelay; + /// Refetch the query whenever the data passed as [externalData] to any + /// [QueryBuilder] or [useQuery] changes + /// + /// If set to false than the [externalData] will get updated but there + /// won't be any query update + final bool refetchOnExternalDataChange; + /// used for periodically checking if any query got stale. /// If none is supplied then half of the value of staleTime is used final Duration refetchInterval; @@ -74,6 +81,7 @@ class QueryBowlScope extends StatefulWidget { this.refetchOnReconnectDelay = const Duration(milliseconds: 100), this.refetchOnApplicationResume = true, this.refetchOnWindowFocus = true, + this.refetchOnExternalDataChange = false, Key? key, }) : super(key: key); @@ -218,6 +226,7 @@ class _QueryBowlScopeState extends State { refetchInterval: widget.refetchInterval, refetchOnMount: widget.refetchOnMount, refetchOnReconnect: widget.refetchOnReconnect, + refetchOnExternalDataChange: widget.refetchOnExternalDataChange, child: widget.child, ); } @@ -237,6 +246,7 @@ class QueryBowl extends InheritedWidget { final Duration? refetchInterval; final bool refetchOnMount; final bool refetchOnReconnect; + final bool refetchOnExternalDataChange; final void Function(Query query) _addQuery; @@ -263,6 +273,7 @@ class QueryBowl extends InheritedWidget { required this.clear, required this.refetchOnMount, required this.refetchOnReconnect, + required this.refetchOnExternalDataChange, this.refetchInterval, Key? key, }) : _addQuery = addQuery, @@ -296,6 +307,7 @@ class QueryBowl extends InheritedWidget { if (onError != null) prevQuery.onErrorListeners.add(onError); if (!prevQuery.hasData || hasExternalDataChanged) { if (hasExternalDataChanged) prevQuery.setExternalData(externalData); + return await prevQuery.refetch(); } // mounting the widget that is using the query in the prevQuery diff --git a/packages/fl_query/lib/src/query_builder.dart b/packages/fl_query/lib/src/query_builder.dart index 87fb814..22f528d 100644 --- a/packages/fl_query/lib/src/query_builder.dart +++ b/packages/fl_query/lib/src/query_builder.dart @@ -77,13 +77,20 @@ class _QueryBuilderState } else if (oldWidget.externalData != null && widget.externalData != null && !isShallowEqual(oldWidget.externalData!, widget.externalData!)) { - QueryBowl.of(context).fetchQuery( - widget.job, - externalData: widget.externalData, - onData: widget.onData, - onError: widget.onError, - key: uKey, - ); + if (widget.job.refetchOnExternalDataChange ?? + queryBowl.refetchOnExternalDataChange) { + QueryBowl.of(context).fetchQuery( + widget.job, + externalData: widget.externalData, + onData: widget.onData, + onError: widget.onError, + key: uKey, + ); + } else { + QueryBowl.of(context) + .getQuery(widget.job.queryKey) + ?.setExternalData(widget.externalData); + } if (hasOnDataChanged) query?.onDataListeners.remove(oldWidget.onData); if (hasOnErrorChanged) query?.onErrorListeners.remove(oldWidget.onError); } else {