apollo-client icon indicating copy to clipboard operation
apollo-client copied to clipboard

useLazyQuery loading not change after first call

Open MajidCybanor opened this issue 2 years ago • 21 comments

@apollo/client : 3.5.5,

 const [fetchCuttings, { loading }] = useLazyQuery(
    queries.CUTTINGS_OPTIMIZED,
    {
      fetchPolicy: "network-only",
      onCompleted(data) {
        const res = getDataFromGraphQLResult(data, "cuttings");
        setCuttingProformaList(
          res.map((item) => {
            return { ...item, workOrder: item?.PINo + item?.name };
          })
        );
      },
      onError({ message }) {
        showError(message);
      },
    }
  );

loading variable changes for only initial call.... it was working perfectly before updating to 3.5.5

MajidCybanor avatar Nov 30 '21 07:11 MajidCybanor

Can confirm that we have the same issue, but with version 3.4.17 - on the first lazyQuery call loading becomes true but on consecutive calls loading stays false even tough we can see the request actually going out in the network tab of developer tools.

This breaks a lot of places of our application :(

Markus-ipse avatar Nov 30 '21 13:11 Markus-ipse

@Markus-ipse Apollo client update is causing many problems. I am applying temporary fixes hoping this will be fixed soon

MajidCybanor avatar Dec 01 '21 08:12 MajidCybanor

Can add up to this issue, I've noticed it after updating from ^3.4.5 to ^3.5.5.

ViktorShapoval avatar Dec 01 '21 14:12 ViktorShapoval

@MajidCybanor What version of @apollo/client were you using before you updated?

benjamn avatar Dec 01 '21 21:12 benjamn

@benjamn 3.3.17

MajidCybanor avatar Dec 02 '21 02:12 MajidCybanor

3.3.20 had this issue as well, i observed that the "stuck in loading" was only true when i provided the onCompleted cb

3.5.5 (latest at the time of writing) fixed it

Psvensso avatar Dec 07 '21 10:12 Psvensso

@Psvensso did 3.3.20 had issues, in which variable persist in subsequent calls

MajidCybanor avatar Dec 08 '21 10:12 MajidCybanor

I'm seeing this in 3.5.6 as well. I think the loading variable never turns off, and since I am using SSR, the entire page never loads.

This is my code. Any work around for the time being?

  const [findItems, { loading, data, error }] = useLazyQuery(
    SEARCH_PRODUCTS_QUERY,
    {
      fetchPolicy: 'no-cache',
    }
  );

wesbos avatar Dec 08 '21 15:12 wesbos

A workaround for now is to only load the component that is using useLazyQuery in the browser, Since it's relies on user interaction, it doesn't need to be SSR

wesbos avatar Dec 08 '21 16:12 wesbos

Same issue with useLazyQuery in 3.5.6.

edouardruiz avatar Dec 08 '21 19:12 edouardruiz

Setting notifyOnNetworkStatusChange to true seems to make the loading status change for subsequent calls.

edouardruiz avatar Dec 09 '21 07:12 edouardruiz

Same issue with apollo/client version 3.5.7.

rohailtaha avatar Jan 26 '22 18:01 rohailtaha

I confirm that the problem exists in apollo/client 3.5.7. I have both onCompleted like @Psvensso and no-cache policy like @wesbos Also I use sokets instead of direct connection.

Thanks to @edouardruiz I managed to fix that with notifyOnNetworkStatusChange set to true.

The description of the option kinda gives me a clue that this this behavior is intended, also I wonder why this is considered good to set option to false as default.

Amantel avatar Jan 28 '22 10:01 Amantel

Setting notifyOnNetworkStatusChange to true seems to make the loading status change for subsequent calls.

thanks works for me

mohamedma872 avatar Mar 02 '22 23:03 mohamedma872

But notifyOnNetworkStatusChange will set loading to true even if you haven't fetched the query manually such as calling fetchCuttings(). This happens because some other query might have updated the cache of the response fetched by fetchCuttings(). Without notifyOnNetworkStatusChange to true, you wouldn't get a notification of that in the loading variable. To me apollo-client seems like cache-first library and it's causing a lot of issues in my applications as well, it's very difficult to control.

thatisuday avatar Apr 28 '22 10:04 thatisuday

I've spent the last couple of hours debugging trying to figure out why a particular (and rather gnarly) flow is broken in our app, only to finally figure it out (loading not updating), going here and checking for issues - and finding this issue that I commented on in November, due to a similar, but totally unrelated bug.. 😩

It seems to me that default should be loading: true if it is actually loading, and then if you don't want that behaviour you should opt out, as opposed to how it is now, where (IMO) you have to opt-in to get the most logical behaviour.

Markus-ipse avatar May 02 '22 13:05 Markus-ipse

I don't mean to minimize the discussion that has been happening here, but some of the common themes in useLazyQuery behavior that folks are describing seem to be working as intended, so I hope I can clarify those intentions a bit:

  • When you use fetchPolicy: "network-only" with useLazyQuery, you will not automatically receive a loading: true result when you call the execution function, because the network-only policy typically only delivers the final network result, which has loading: false
    • Other fetch policies like cache-and-network and cache-first may deliver loading: true results followed by loading: false results, but network-only defaults to delivering only the final loading: false result
  • If you want to receive the extra loading: true result, then notifyOnNetworkStatusChange: true is the way to achieve that

We had some other issues with useLazyQuery in v3.5.x that I believe have been resolved in v3.6.x. Please try updating with npm i @apollo/[email protected] to make sure you're not hitting those other problems. After updating, if what I wrote above seems inaccurate, please let us know here (or in a new issue).

If I am recalling correctly, there were some previous versions of Apollo Client where notifyOnNetworkStatusChange: true wasn't really necessary in some cases because loading: true results would get delivered anyway. I am sorry if your applications depended on those quirks and inconsistencies, but I would rather have the fetch policies do what they promise (e.g. network-only only delivers network results), with options like notifyOnNetworkStatusChange available when you need to modify the default behavior.

benjamn avatar May 02 '22 14:05 benjamn

Thanks for your answer @benjamn! If I may ask for a bit of clarification, what is the reasoning for not setting loading: true when the policy is networkOnly?

I am sorry if your applications depended on those quirks and inconsistencies, but I would rather have the fetch policies do what they promise (e.g. network-only only delivers network results)

I'm quite confused by this part ☝️ how would saying we're waiting for data from the network, i.e. loading: true not be appropriate when the fetchPolicy is networkOnly?

I'm not trying to be argumentative here, so I'm sorry if it comes of as that - I'm really just trying to understand 🙂

Markus-ipse avatar May 03 '22 07:05 Markus-ipse

There needs to be a FetchPolicy that gives you only the final network result, without an extra loading: true result, because delivering that extra result triggers a potentially unnecessary rerendering of your component, making it difficult to implement the pattern of rerendering the UI only when the actual data have changed (because the loading: true result always rerenders the UI anyway). The network-only fetch policy is that policy.

If you want the extra loading: true result, you can either use cache-and-network instead, or add the notifyOnNetworkStatusChange: true option when using network-only. Because these other (more explicit) options exist, it's important (in my mind) to preserve the default behavior and capabilities of network-only.

If we made it so network-only always delivered a loading: true result, as some folks seem to want, then network-only would become confusingly similar in meaning to cache-and-network. That crossing of purposes makes the fetch policy system harder to understand/navigate, and deprives the developer of meaningful choices/control.

benjamn avatar May 03 '22 14:05 benjamn

So for me similar issue started happening last night in the middle of my development (haven't changed anything regarding apollo-client). I am working with React Native project btw. To briefly describe, every lazy query in my app is literally is behaving like this:

  1. call the query
  2. loading is true
  3. and response stays that way (Sometimes I can get the response to update if I call the query again)
  4. network logs from debugger clearly show that data has been returned but response part of lazy query never changes to reflect that (so my app is basically not functional at this point)

I have lost half of my day trying to figure out what is happening and how to solve this (tried every fetch policy). Updating to newest version does not help either. Versions tried:

  • "@apollo/client": "^3.5.10"
  • "@apollo/client": "^3.6.2"

Versions that have been released to the team before with the same setup are not affected by this.

asapMaki avatar May 04 '22 19:05 asapMaki

Hi,

So I can't quite remember how I solved it, but current setup is @.***/client": "^3.6.2",

and I did change the links from client.setLink(from([errorLink, authLink(token).concat(httpLink)])); to client.setLink(from([errorLink, authLink(token), httpLink])); I also updated apollo in my dev dependency. Not sure if this is helpful but I do not see this problem anymore

On Thu, May 26, 2022 at 7:58 AM Jonathan Adami @.***> wrote:

I have a similar issue with 2 concurrent queries, one using useQuery, one using useLazyQuery, they happen separately in the code but apollo groups the queries together (which is pretty neat). I can see both queries properly formed, the server answers with all the data required, but neither useQuery nor useLazyQuery gets updated with the appropriate data.

I've tried the network variable thingy to no avail.

I'm using @apollo/client 3.6.5 and this used to work before :/

Any help would be gratefully received.

— Reply to this email directly, view it on GitHub https://github.com/apollographql/apollo-client/issues/9137#issuecomment-1138183396, or unsubscribe https://github.com/notifications/unsubscribe-auth/AHGNEPBIYGYDRIJY2D3XEBLVL4HHJANCNFSM5JBB7O5A . You are receiving this because you commented.Message ID: @.***>

asapMaki avatar May 26 '22 10:05 asapMaki

Hi all, I'm doing some housekeeping and came across this issue. Reading through the conversation above, per @benjamn's comment this is the intended behavior. Thanks all for your thoughts and for the helpful suggestions!

bignimbus avatar Dec 08 '22 22:12 bignimbus