Graphql-flutter: Why is the Query call to server multiple times

Created on 1 Mar 2020  路  11Comments  路  Source: zino-app/graphql-flutter

Describe the bug
The Query Widget call to server multiple times.
When I used the FetchPolicy.cacheAndNetwork, I understand the twice builder call.
But, in my case, the builder method is calling three times and sometimes calls more.

To Reproduce
Steps to reproduce the behavior:

# my code
@override
Widget build(BuildContext context) {
  print('build');

  return Query(
    options: {
      ...
      fetchPolicy: FetchPolicy.cacheAndNetwork,
      ...
},
    builder: (QueryResult result, {Refetch refetch, FetchMore fetchMore}) {
      if (result.loading ) {
        return Loader();
      }

      if (result.hasException) {
          return Container();
      }

      print('builder');
      ...
    },
  );
}

Expected behavior
Call one time to server.

Screenshots

# in console
flutter: build
flutter: builder
flutter: builder
flutter: builder
# in server console
...
app:GetGroupLabels resolver +6ms
...
app:GetGroupLabels resolver +2ms
...
POST /graphql 200 12.968 ms - 893
POST /graphql 200 15.661 ms - 893

Desktop (please complete the following information):

  • OS: MacOS
  • Version 10.14

Smartphone (please complete the following information):

  • Device: iPhone8
  • OS: iOS12.2

Additional context
Add any other context about the problem here.

Most helpful comment

We found another bug that causes queries to be run multiple times in certain cases despite the fix in #533. That happens when:

  1. Query is rebuilt by the parent. In the context of Navigator push/pop, this happens when Query has a stateful ancestor since every state seems to be built again when push/pop. See https://github.com/flutter/flutter/issues/11655
  2. QueryState.didUpdateWidget is called, and it tries to compare the old and new options to decide whether to rebuild ObservableQuery.
  3. Here is the actual bug: WatchQueryOptions.areEqualTo() does not consider default policy overrides. So when a query does not have fetch or error policies set, the equality check will fail, causing ObservableQuery to be rebuilt.

All 11 comments

I'm having the same issue. I have a query calling 3 times in a row and causing a problem. I could be doing something wrong but I can't figure it out.

At first I thought it might be related to this: #121 but I don't think it is because I can see that it's hitting the network 3 times with the same exact request based on the logging in my server.

This is an issue because when I first load a page I make a mutation to update a couple things but I don't want to show the updates until the next time the page is visited. However because it calls the endpoint multiple times this does not work.

Are you guys using Navigator?
I found it is true that it fetches multiple times when route changes and also on App Drawer closing as well.

@chungwong Yes, I use Navigator with MaterialPageRoute.
And last night, I found the rebuild issue causing by MaterialPageRoute.
In my case, Changed the maintaionState of MaterialPageRoute props to false was solved this issue.

I ignored the prev screen's behavior.

I believe it is more than just related to MaterialPageRoute

There is already a PR addressing this issue.
https://github.com/zino-app/graphql-flutter/pull/533

I am facing the same problem, the build being done two times it麓s expected. But the query being done to server multiple times is a problem and i cant figure out why.

@pepomps Do you use MaterialPageRoute ?
In my case, the background pages in MaterialPageRoute was rebuilding when the global states changing like page navigation.
If you use MaterialPageRoute, what about check the maintaionState of MaterialPageRoute props ?

@chicrok I just implemented your solution, the problem was in MaterialPageRout, now it's working! thanks for the help!!

I have the same problem and I don't know how to solve it.
Can you explain a little more in detail?
Please
I am using the graphql_flutter version: ^ 2.1.1-beta.5

Sorry, could you show an example of how to make a query and not to do it three times?
I still can't do it with version 3.1.0-beta.2

It doesn't work for me using the latest beta version of the package. Could you upload an example of how to make a query using the wiget Query and not make three requests to the server?
Thank you

@joseignaciopergolesi Did you play this ? (https://github.com/zino-app/graphql-flutter/issues/575#issuecomment-606965332)
In my case, MaterialPageRoute caused this problem..

We found another bug that causes queries to be run multiple times in certain cases despite the fix in #533. That happens when:

  1. Query is rebuilt by the parent. In the context of Navigator push/pop, this happens when Query has a stateful ancestor since every state seems to be built again when push/pop. See https://github.com/flutter/flutter/issues/11655
  2. QueryState.didUpdateWidget is called, and it tries to compare the old and new options to decide whether to rebuild ObservableQuery.
  3. Here is the actual bug: WatchQueryOptions.areEqualTo() does not consider default policy overrides. So when a query does not have fetch or error policies set, the equality check will fail, causing ObservableQuery to be rebuilt.
Was this page helpful?
0 / 5 - 0 ratings