D-James-GH / cached_query

Simple caching for flutter apps
MIT License
55 stars 10 forks source link

feat: invalidateQueryAndRefetchIfListeners() #28

Open iOSonntag opened 6 months ago

iOSonntag commented 6 months ago

First of all great work!

Regarding my issue, I searched ages and dived deep into the framework code on how to be able to invalidate a query and only refetch it, if it actually is used somewhere. Turns out its not possible out of the box so I wrote myself an extension:

extension ExtensionOnQueryBase<T, State extends QueryState<dynamic>> on QueryBase<T, State> {

  void invalidateQueryAndRefetchIfListeners()
  {
    invalidateQuery();

    if (hasListener) refetch();
  }
}

I know the name is not the best, but explaining people that this is what you want regarding not asking the server to much and still having a nice user experience and it is not shipped within the docs or the framework might be an issue for many people beeing guided in the wrong driection IMO

D-James-GH commented 5 months ago

Not sure about adding in another feature for this as this can be done either as you have done for a single query or with a query search eg:

// reftech all querys with listeners
CachedQuery.instance.refetchCurrentQueries();

// invalidate all queries
CachedQuery.instance.invalidateCache();

// or using a where search for more control
final queries = CachedQuery.instance.whereQuery((query) => !query.hasListener);

However, the docs should be improved if you were unable to find this information. Or even adding your suggestion to the docs. Are there any part of the docs that you feel are miss leading? Have I missed anything or miss understood your request?

iOSonntag commented 5 months ago

No, you are completely right with what you just said.

Maybe pointing it out in the docs would be great for new developers. I ran into this case often, like have a list of Items then going to the detail page of 1 Item updating the Item and invalidate the list of Items and refetch it if a screen is open displaying the list of Items (list query having listeners).

Of course you could have updated the list query manually with the newly recieved item from the update call. But this adds another layer of complexity to the developer and often times its much easier to just invalidate those queries and refetch them.

And because I only saw invalidate() and refetch() I thought it is possible to do it with one of those functions.

To be honest I can only imagine a few special cases where you wanna refetch a query that is not beeing used. I was thinking about something like refetch({bool onlyIfUsed = false}) that would not break anyones code but still has the direct option. The problem is that you would have to call invalidate() before that regardless of the refetch because it could stop the refetch().

So I Guess you are right putting it somewhere in the docs might be a good place to start.

iOSonntag commented 5 months ago

Just to explain my example more, often times I had api calls I knew would change my infinite lists but had no return object to optimistic update that list. Either I am coding wrong or this happens a lot of times :D