Skip to content

Commit

Permalink
Merge pull request zino-hofmann#377 from zino-app/beta
Browse files Browse the repository at this point in the history
Promote Beta to Stable
  • Loading branch information
HofmannZ authored Aug 8, 2019
2 parents d5508a5 + 685d437 commit ba98de9
Show file tree
Hide file tree
Showing 16 changed files with 429 additions and 39 deletions.
61 changes: 46 additions & 15 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -201,41 +201,72 @@ jobs:
cd packages/graphql_flutter
pub publish -f
workflows:
default:
jobs:
- dependencies:
nightly:
triggers:
- schedule:
cron: "0 0 * * *"
filters:
tags:
only: /^.*$/
branches:
only:
- beta
jobs:
- dependencies
- lint:
requires:
- dependencies
filters:
tags:
ignore: /^.*$/
- coverage:
requires:
- dependencies
filters:
tags:
ignore: /^.*$/
- release:
requires:
- dependencies
- lint
- coverage
- sync_with_beta:
requires:
- release
weekly:
triggers:
- schedule:
cron: "0 21 * * 1"
filters:
branches:
only:
- master
- beta
jobs:
- dependencies
- lint:
requires:
- dependencies
- coverage:
requires:
- dependencies
- release:
requires:
- dependencies
- lint
- coverage
- sync_with_beta:
requires:
- release
default:
jobs:
- dependencies:
filters:
branches:
only:
- master
tags:
only: /^.*$/
- lint:
requires:
- dependencies
filters:
tags:
ignore: /^.*$/
- coverage:
requires:
- dependencies
filters:
tags:
ignore: /^.*$/
- publish:
requires:
- dependencies
Expand Down
4 changes: 4 additions & 0 deletions cloudbuild.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
steps:
- name: 'gcr.io/cloud-builders/npm'
entrypoint: 'node'
args: ['--version']
2 changes: 1 addition & 1 deletion examples/starwars/lib/client_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ ValueNotifier<GraphQLClient> clientFor({
@required String uri,
String subscriptionUri,
}) {
Link link = HttpLink(uri: uri) as Link;
Link link = HttpLink(uri: uri);
if (subscriptionUri != null) {
final WebSocketLink websocketLink = WebSocketLink(
url: subscriptionUri,
Expand Down
6 changes: 5 additions & 1 deletion examples/starwars/lib/episode/hero_query.dart
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,11 @@ class HeroForEpisode extends StatelessWidget {
'ep': episodeToJson(episode),
},
),
builder: (QueryResult result, {BoolCallback refetch}) {
builder: (
QueryResult result, {
BoolCallback refetch,
FetchMore fetchMore,
}) {
if (result.errors != null) {
return Text(result.errors.toString());
}
Expand Down
2 changes: 1 addition & 1 deletion packages/graphql/lib/src/core/graphql_error.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class GraphQLError {

/// Constructs a [GraphQLError] from a JSON map.
GraphQLError.fromJSON(this.raw)
: message = raw['message'] as String,
: message = raw['message'] is String ? raw['message'] as String : 'Invalid server response: message property needs to be of type String',
locations = raw['locations'] is List<Map<String, int>>
? List<Location>.from(
(raw['locations'] as List<Map<String, int>>).map<Location>(
Expand Down
51 changes: 51 additions & 0 deletions packages/graphql/lib/src/core/observable_query.dart
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,57 @@ class ObservableQuery {
return allResults;
}

/// fetch more results and then merge them according to the updateQuery method.
/// the results will then be added to to stream for the widget to re-build
void fetchMore(FetchMoreOptions fetchMoreOptions) async {
// fetch more and udpate
assert(fetchMoreOptions.updateQuery != null);

final combinedOptions = QueryOptions(
fetchPolicy: FetchPolicy.networkOnly,
errorPolicy: options.errorPolicy,
document: fetchMoreOptions.document ?? options.document,
context: options.context,
variables: {
...options.variables,
...fetchMoreOptions.variables,
},
);

// stream old results with a loading indicator
addResult(QueryResult(
data: latestResult.data,
loading: true,
));

QueryResult fetchMoreResult = await queryManager.query(combinedOptions);

try {
fetchMoreResult.data = fetchMoreOptions.updateQuery(
latestResult.data,
fetchMoreResult.data,
);
assert(fetchMoreResult.data != null, 'updateQuery result cannot be null');
} catch (error) {
if (fetchMoreResult.hasErrors) {
// because the updateQuery failure might have been because of these errors,
// we just add them to the old errors
latestResult.errors = [
...(latestResult.errors ?? const []),
...fetchMoreResult.errors
];
addResult(latestResult);
return;
} else {
rethrow;
}
}

// combine the query with the new query, using the fucntion provided by the user
// stream the new results and rebuild
addResult(fetchMoreResult);
}

/// add a result to the stream,
/// copying `loading` and `optimistic`
/// from the `latestResult` if they aren't set.
Expand Down
22 changes: 22 additions & 0 deletions packages/graphql/lib/src/core/query_options.dart
Original file line number Diff line number Diff line change
Expand Up @@ -168,3 +168,25 @@ class WatchQueryOptions extends QueryOptions {
return areDifferentVariables(a.variables, b.variables);
}
}

/// merge fetchMore result data with earlier result data
typedef dynamic UpdateQuery(
dynamic previousResultData,
dynamic fetchMoreResultData,
);

/// options for fetchmore operations
class FetchMoreOptions {
FetchMoreOptions({
this.document,
this.variables = const <String, dynamic>{},
@required this.updateQuery,
}) : assert(updateQuery != null);

final String document;
final Map<String, dynamic> variables;

/// Strategy for merging the fetchMore result data
/// with the result data already in the cache
UpdateQuery updateQuery;
}
4 changes: 2 additions & 2 deletions packages/graphql/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: graphql
description: A stand-alone GraphQL client for Dart, bringing all the features from
a modern GraphQL client to one easy to use package.
version: 2.0.1
version: 2.1.0-beta.1
authors:
- Eus Dima <[email protected]>
- Zino Hofmann <[email protected]>
Expand All @@ -24,4 +24,4 @@ dev_dependencies:
test: ^1.5.3
test_coverage: ^0.2.0
environment:
sdk: '>=2.2.0 <3.0.0'
sdk: '>=2.2.2 <3.0.0'
80 changes: 66 additions & 14 deletions packages/graphql_flutter/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,20 @@

## Table of Contents

- [Installation](#Installation)
- [Usage](#Usage)
- [GraphQL Provider](#GraphQL-Provider)
- [Offline Cache](#Offline-Cache)
- [Normalization](#Normalization)
- [Optimism](#Optimism)
- [Queries](#Queries)
- [Mutations](#Mutations)
- [Mutations with optimism](#Mutations-with-optimism)
- [Subscriptions (Experimental)](#Subscriptions-Experimental)
- [GraphQL Consumer](#GraphQL-Consumer)
- [GraphQL Upload](#GraphQL-Upload)
- [Roadmap](#Roadmap)
- [Installation](#installation)
- [Usage](#usage)
- [GraphQL Provider](#graphql-provider)
- [Offline Cache](#offline-cache)
- [Normalization](#normalization)
- [Optimism](#optimism)
- [Queries](#queries)
- [Fetch More (Pagination)](#fetch-more-pagination)
- [Mutations](#mutations)
- [Mutations with optimism](#mutations-with-optimism)
- [Subscriptions (Experimental)](#subscriptions-experimental)
- [GraphQL Consumer](#graphql-consumer)
- [GraphQL Upload](#graphql-upload)
- [Roadmap](#roadmap)

## Installation

Expand Down Expand Up @@ -200,7 +201,8 @@ Query(
pollInterval: 10,
),
// Just like in apollo refetch() could be used to manually trigger a refetch
builder: (QueryResult result, { VoidCallback refetch }) {
// while fetchMore() can be used for pagination purpose
builder: (QueryResult result, { VoidCallback refetch, FetchMore fetchMore }) {
if (result.errors != null) {
return Text(result.errors.toString());
}
Expand All @@ -224,6 +226,56 @@ Query(
// ...
```

#### Fetch More (Pagination)

You can use `fetchMore()` function inside `Query` Builder to perform pagination. The `fetchMore()` function allows you to run an entirely new GraphQL operation and merge the new results with the original results. On top of that, you can re-use aspects of the Original query i.e. the Query or some of the Variables.

In order to use the `FetchMore()` function, you will need to first define `FetchMoreOptions` variable for the new query.

```dart
...
// this is returned by the GitHubs GraphQL API for pagination purpose
final Map pageInfo = result.data['search']['pageInfo'];
final String fetchMoreCursor = pageInfo['endCursor'];
FetchMoreOptions opts = FetchMoreOptions(
variables: {'cursor': fetchMoreCursor},
updateQuery: (previousResultData, fetchMoreResultData) {
// this function will be called so as to combine both the original and fetchMore results
// it allows you to combine them as you would like
final List<dynamic> repos = [
...previousResultData['search']['nodes'] as List<dynamic>,
...fetchMoreResultData['search']['nodes'] as List<dynamic>
];
// to avoid a lot of work, lets just update the list of repos in returned
// data with new data, this also ensure we have the endCursor already set
// correctly
fetchMoreResultData['search']['nodes'] = repos;
return fetchMoreResultData;
},
);
...
```

And then, call the `fetchMore()` function and pass the `FetchMoreOptions` variable you defined above.

```dart
RaisedButton(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text("Load More"),
],
),
onPressed: () {
fetchMore(opts);
},
)
```

### Mutations

Again first create a mutation string:
Expand Down
Loading

0 comments on commit ba98de9

Please sign in to comment.