Skip to content

Instantly share code, notes, and snippets.

@micimize
Last active May 20, 2020 18:54
Show Gist options
  • Save micimize/cd51edf60d0c3f4cd04c2b78218890f1 to your computer and use it in GitHub Desktop.
Save micimize/cd51edf60d0c3f4cd04c2b78218890f1 to your computer and use it in GitHub Desktop.
extension FetchMore on GraphQLClient {
/// fetch more results and then merge them with [previousResult]
/// according to [FetchMoreOptions.updateQuery]
Future<QueryResult> fetchMore(
FetchMoreOptions fetchMoreOptions, {
@required QueryOptions options,
@required QueryResult previousResult,
/// rebroadcast other queries unless caching is disabled
/// for this query via `options`
bool rebroadcastQueries = true,
}) async {
// fetch more and udpate
assert(fetchMoreOptions.updateQuery != null);
final documentNode =
(fetchMoreOptions.documentNode ?? options.documentNode);
assert(
documentNode != null,
'Either fetchMoreOptions.documentNode '
'or the previous QueryOptions must be supplied!',
);
final combinedOptions = QueryOptions(
fetchPolicy: FetchPolicy.noCache,
errorPolicy: options.errorPolicy,
documentNode: documentNode,
variables: {
...options.variables,
...fetchMoreOptions.variables,
},
);
QueryResult fetchMoreResult = await queryManager.query(combinedOptions);
try {
// combine the query with the new query, using the function provided by the user
fetchMoreResult.data = fetchMoreOptions.updateQuery(
previousResult.data,
fetchMoreResult.data,
);
assert(fetchMoreResult.data != null, 'updateQuery result cannot be null');
if (options.fetchPolicy ??
defaultPolicies.query.fetch != FetchPolicy.noCache) {
cache.write(
options.toKey(),
fetchMoreResult.data,
);
if (rebroadcastQueries) {
queryManager.rebroadcastQueries();
}
}
} catch (error) {
if (fetchMoreResult.hasException) {
// because the updateQuery failure might have been because of these errors,
// we just add them to the old errors
previousResult.exception = _coalesceErrors(
exception: previousResult.exception,
graphqlErrors: fetchMoreResult.exception.graphqlErrors,
clientException: fetchMoreResult.exception.clientException,
);
return previousResult;
} else {
// TODO merge results OperationException
rethrow;
}
}
return fetchMoreResult;
}
}
/// `(graphqlErrors?, exception?) => exception?`
///
/// merges both optional graphqlErrors and an optional container
/// into a single optional container
/// NOTE: NULL returns expected
OperationException _coalesceErrors({
List<GraphQLError> graphqlErrors,
ClientException clientException,
OperationException exception,
}) {
if (exception != null ||
clientException != null ||
(graphqlErrors != null && graphqlErrors.isNotEmpty)) {
return OperationException(
clientException: clientException ?? exception?.clientException,
graphqlErrors: [
if (graphqlErrors != null) ...graphqlErrors,
if (exception?.graphqlErrors != null) ...exception.graphqlErrors
],
);
}
return null;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment