zino-hofmann / graphql-flutter

A GraphQL client for Flutter, bringing all the features from a modern GraphQL client to one easy to use package.
https://zino-hofmann.github.io/graphql-flutter
MIT License
3.25k stars 622 forks source link

Query data without widgets ignores fetch policies #1346

Closed amoossssss closed 1 year ago

amoossssss commented 1 year ago

I tried to fetch data without building widgets and found that the query kept returning results from the cache. I updated the user's info through RESTFUL POST API, and when I re-fetched the user's data, it uses the cache instead of network data.

My graphql client is defined as below:

final HttpLink httpLink = HttpLink('$baseUrl/...');

final policies = Policies(
    fetch: FetchPolicy.networkOnly,
    cacheReread: CacheRereadPolicy.ignoreAll,
    error: ErrorPolicy.all);

ValueNotifier<GraphQLClient> gqlClient = ValueNotifier(
  GraphQLClient(
      link: httpLink,
      cache: GraphQLCache(store: HiveStore()),
      defaultPolicies: DefaultPolicies(query: policies)),
);

Inside my flutter widget, I called a gqlReadMember function to retrieve member data from the server.

I defined gqlReadMember as below, it is defined in a MemberService class, and it calls readMember inside the body.

var readMember = gqlClient.value.query(QueryOptions(
  document: gql(getMember),
  fetchPolicy: FetchPolicy.networkOnly,
  cacheRereadPolicy: CacheRereadPolicy.ignoreAll,
));
class MemberService {
  ...

  Future<List<MemberResponse>> gqlReadMember() async {
    var result = await readMember;
    List data = result.data?["members"];
    return data.map((item) => MemberResponse.fromJson(item)).toList();
  }
}

Even with fetchPolicy: FetchPolicy.networkOnly specified, the results are not from the server.

When I used the Query widget with fetchPolicy set to network only, it works as I expected.

e.g.

Query(
  options: QueryOptions(
    document: gql(getMember),
    fetchPolicy: FetchPolicy.noCache,
    errorPolicy: ErrorPolicy.none,
    cacheRereadPolicy: CacheRereadPolicy.ignoreAll,
  ),
  builder: (QueryResult result,
      {VoidCallback? refetch, FetchMore? fetchMore}) {
    if (result.hasException) {
      return Text(result.exception.toString());
    }

    if (result.isLoading) {
      return const Text('Loading');
    }

    List? members = result.data?['members'];

    if (members == null) {
      return const Text('No members');
    }

    return ListView.builder(
        shrinkWrap: true,
        itemCount: members.length,
        itemBuilder: (context, index) {
          final member = members[index];

          return Text(member['nickname'] ?? '');
        });
  },
)

I am wondering if any mistakes or missed setups are made with my current implementation. Thanks for your support in advanced! 🙏

graphql_flutter: ^5.1.2