diff --git a/docs/docs/basics/LazyQuery.md b/docs/docs/basics/LazyQuery.md index 0ab9f63..c5d368e 100644 --- a/docs/docs/basics/LazyQuery.md +++ b/docs/docs/basics/LazyQuery.md @@ -1,4 +1,55 @@ --- title: Lazy Query sidebar_position: 7 ---- \ No newline at end of file +--- + +If you ever want to disable a query from automatically running, you can use the enabled = false option in [`QueryJob`](/docs/basics/QueryJob) + +When `enabled` is false: + +- If the query has initial data + - The query will be initialized in the status === 'success' or isSuccess state. +- If the query does not have any data + - The query will start in the status === 'idle' or isIdle state. +- The query will not automatically `fetch` on mount. +- The query will not automatically `refetch` in the background when new instances mount or new instances appearing +- The query will ignore query client `invalidateQueries` and `refetchQueries` calls that would normally result in the query refetching. +- `refetch` can be used to manually trigger the query to fetch + +Here's a basic QueryJob that won't run automatically: + +```dart +final lazyQueryJob = QueryJob( + queryKey: "lazy-query", + enabled: false, + task: (queryKey, data) { + return Future.delayed(const Duration(milliseconds: 500), + () => "Result: key=$queryKey value=$data"); + }, +); +``` + +Let's use this Lazy Query Job in our example: + +```dart + @override + Widget build(BuildContext context) { + return QueryBuilder( + // This query won't run automatically anyway unless the [refetch] method + // is called + job: lazyQueryJob, + externalData: "I can get your heart beat beat beat beating like", + builder: (context, query) { + return Row( + children: [ + Text("Current Data: ${query.data ?? "Loading"}"), + ElevatedButton( + child: const Text("Refetch Query"), + onPressed: () => query.refetch(), + ), + ], + ); + }, + ); + } +``` \ No newline at end of file diff --git a/docs/docs/basics/OptimisticUpdates.md b/docs/docs/basics/OptimisticUpdates.md new file mode 100644 index 0000000..9455629 --- /dev/null +++ b/docs/docs/basics/OptimisticUpdates.md @@ -0,0 +1,49 @@ +--- +title: Optimistic Updates (Still WIP) +sidebar_position: 10 +--- + +### What is Optimistic UI Update? + +> In an optimistic update the UI behaves as though a change was successfully completed before receiving confirmation from the server that it actually was - it is being optimistic that it will eventually get the confirmation rather than an error. This allows for a more responsive user experience. +> +> Source: https://stackoverflow.com/a/33009713/13292290 + +# Update from Mutation Response + +When dealing with mutations that **update** documents/tables on the server, it's common for the new data to be automatically returned in the response of the `mutation`. Instead of refetching any queries for that item and wasting a network call for data we already have, we can take advantage of the object returned by the mutation function and update the existing query with the new data immediately using the `QueryBowl`'s `setQueryData` method: + +```dart +return MutationBuilder( + job: mutationJob, + onSuccess: (data) { + QueryBowl.of(context) + .setQueryData(successJob.queryKey, (_oldData) { + return data; + }); + } +); +``` + +# onMutate Event Callback + +`onMutate` callback of `MutationBuilder` runs before the mutation task defined in the `MutationJob` is executed. It gives access to mutation variables in the Callback too thus queries or any other source of data can be updated with predicted data to make user experience a lot smoother + + +```dart +return MutationBuilder( + job: mutationJob, + onMutate: (variable) { + QueryBowl.of(context) + .setQueryData, void>(successJob.queryKey, (oldData) { + // replacing the soon to be expired data with updated data + return {...oldData, ...variable}; + }); + + // here we should be able to return a previous snapshot + // of the intended query data which can be used when + // an error occurs in mutation & we can rollback to a previous + // data set + } +); +``` \ No newline at end of file