graphql_flutter 2.1.0

  • Readme
  • Changelog
  • Example
  • Installing
  • 80

MIT License All Contributors PRs Welcome

Star on GitHub Watch on GitHub Discord

Build Status Coverage version

GraphQL Flutter #

Table of Contents #

Installation #

First, depends on the library by adding this to your packages pubspec.yaml:

dependencies:
  graphql_flutter: ^2.0.0

Now inside your Dart code, you can import it.

import 'package:graphql_flutter/graphql_flutter.dart';

Usage #

To use the client it first needs to be initialized with a link and cache. For this example, we will be using an HttpLink as our link and InMemoryCache as our cache. If your endpoint requires authentication you can concatenate the AuthLink, it resolves the credentials using a future, so you can authenticate asynchronously.

For this example we will use the public GitHub API.

...

import 'package:graphql_flutter/graphql_flutter.dart';

void main() {
  final HttpLink httpLink = HttpLink(
    uri: 'https://api.github.com/graphql',
  );

  final AuthLink authLink = AuthLink(
    getToken: () async => 'Bearer <YOUR_PERSONAL_ACCESS_TOKEN>',
    // OR
    // getToken: () => 'Bearer <YOUR_PERSONAL_ACCESS_TOKEN>',
  );

  final Link link = authLink.concat(httpLink);

  ValueNotifier<GraphQLClient> client = ValueNotifier(
    GraphQLClient(
      cache: InMemoryCache(),
      link: link,
    ),
  );

  ...
}

...

GraphQL Provider #

In order to use the client, you Query and Mutation widgets to be wrapped with the GraphQLProvider widget.

We recommend wrapping your MaterialApp with the GraphQLProvider widget.

  ...

  return GraphQLProvider(
    client: client,
    child: MaterialApp(
      title: 'Flutter Demo',
      ...
    ),
  );

  ...

Offline Cache #

The in-memory cache can automatically be saved to and restored from offline storage. Setting it up is as easy as wrapping your app with the CacheProvider widget.

It is required to place the CacheProvider widget is inside the GraphQLProvider widget, because GraphQLProvider makes client available through the build context.

...

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return GraphQLProvider(
      client: client,
      child: CacheProvider(
        child: MaterialApp(
          title: 'Flutter Demo',
          ...
        ),
      ),
    );
  }
}

...

Normalization #

To enable apollo-like normalization, use a NormalizedInMemoryCache or OptimisticCache:

ValueNotifier<GraphQLClient> client = ValueNotifier(
  GraphQLClient(
    cache: NormalizedInMemoryCache(
      dataIdFromObject: typenameDataIdFromObject,
    ),
    link: link,
  ),
);

dataIdFromObject is required and has no defaults. Our implementation is similar to Apollo's, requiring a function to return a universally unique string or null. The predefined typenameDataIdFromObject we provide is similar to apollo's default:

String typenameDataIdFromObject(Object object) {
  if (object is Map<String, Object> &&
      object.containsKey('__typename') &&
      object.containsKey('id')) {
    return "${object['__typename']}/${object['id']}";
  }
  return null;
}

However, note that graphql-flutter does not inject __typename into operations the way Apollo does, so if you aren't careful to request them in your query, this normalization scheme is not possible.

Unlike Apollo, we don't have a real client-side document parser and resolver, so operations leveraging normalization can have additional fields not specified in the query. There are a couple of ideas for constraining this (leveraging json_serializable, or just implementing the resolver), but for now, the normalized cache uses a LazyCacheMap, which wraps underlying data with a lazy denormalizer to allow for cyclical references. It has the same API as a normal HashMap, but is currently a bit hard to debug with, as a descriptive debug representation is currently unavailable.

NOTE: A LazyCacheMap can be modified, but this does not affect the underlying entities in the cache. If references are added to the map, they will still dereference against the cache normally.

Optimism #

The OptimisticCache allows for optimistic mutations by passing an optimisticResult to RunMutation. It will then call update(Cache cache, QueryResult result) twice (once eagerly with optimisticResult), and rebroadcast all queries with the optimistic cache. You can tell which entities in the cache are optimistic through the .isOptimistic flag on LazyCacheMap, though note that this is only the case for optimistic entities and not their containing operations/maps.

QueryResults also, have an optimistic flag, but I would recommend looking at the data itself, as many situations make it unusable (such as toggling mutations like in the example below). Mutation usage examples

Queries #

Creating a query is as simple as creating a multiline string:

String readRepositories = """
  query ReadRepositories(\$nRepositories: Int!) {
    viewer {
      repositories(last: \$nRepositories) {
        nodes {
          id
          name
          viewerHasStarred
        }
      }
    }
  }
""";

In your widget:

// ...
Query(
  options: QueryOptions(
    document: readRepositories, // this is the query string you just created
    variables: {
      'nRepositories': 50,
    },
    pollInterval: 10,
  ),
  // Just like in apollo refetch() could be used to manually trigger a 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());
    }

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

    // it can be either Map or List
    List repositories = result.data['viewer']['repositories']['nodes'];

    return ListView.builder(
      itemCount: repositories.length,
      itemBuilder: (context, index) {
        final repository = repositories[index];

        return Text(repository['name']);
    });
  },
);
// ...

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.

...
// 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.

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

Mutations #

Again first create a mutation string:

String addStar = """
  mutation AddStar(\$starrableId: ID!) {
    addStar(input: {starrableId: \$starrableId}) {
      starrable {
        viewerHasStarred
      }
    }
  }
""";

The syntax for mutations is fairly similar to that of a query. The only difference is that the first argument of the builder function is a mutation function. Just call it to trigger the mutations (Yeah we deliberately stole this from react-apollo.)

...

Mutation(
  options: MutationOptions(
    document: addStar, // this is the mutation string you just created
  ),
  builder: (
    RunMutation runMutation,
    QueryResult result,
  ) {
    return FloatingActionButton(
      onPressed: () => runMutation({
        'starrableId': <A_STARTABLE_REPOSITORY_ID>,
      }),
      tooltip: 'Star',
      child: Icon(Icons.star),
    );
  },
  // you can update the cache based on results
  update: (Cache cache, QueryResult result) {
    return cache;
  },
  // or do something with the result.data on completion
  onCompleted: (dynamic resultData) {
    print(resultData);
  },
);

...

Mutations with optimism #

If you're using an OptimisticCache, you can provide an optimisticResult:

...
FlutterWidget(
  onTap: () {
    toggleStar(
      { 'starrableId': repository['id'] },
      optimisticResult: {
        'action': {
          'starrable': {'viewerHasStarred': !starred}
        }
      },
    );
  },
)
...

With a bit more context (taken from the complete mutation example StarrableRepository):

// bool get starred => repository['viewerHasStarred'] as bool;
// bool get optimistic => (repository as LazyCacheMap).isOptimistic;
Mutation(
  options: MutationOptions(
    document: starred ? mutations.removeStar : mutations.addStar,
  ),
  builder: (RunMutation toggleStar, QueryResult result) {
    return ListTile(
      leading: starred
          ? const Icon(
              Icons.star,
              color: Colors.amber,
            )
          : const Icon(Icons.star_border),
      trailing: result.loading || optimistic
          ? const CircularProgressIndicator()
          : null,
      title: Text(repository['name'] as String),
      onTap: () {
        toggleStar(
          { 'starrableId': repository['id'] },
          optimisticResult: {
            'action': {
              'starrable': {'viewerHasStarred': !starred}
            }
          },
        );
      },
    );
  },
  // will be called for both optimistic and final results
  update: (Cache cache, QueryResult result) {
    if (result.hasErrors) {
      print(['optimistic', result.errors]);
    } else {
      final Map<String, Object> updated =
          Map<String, Object>.from(repository)
            ..addAll(extractRepositoryData(result.data));
      cache.write(typenameDataIdFromObject(updated), updated);
    }
  },
  // will only be called for final result
  onCompleted: (dynamic resultData) {
    showDialog<AlertDialog>(
      context: context,
      builder: (BuildContext context) {
        return AlertDialog(
          title: Text(
            extractRepositoryData(resultData)['viewerHasStarred'] as bool
                ? 'Thanks for your star!'
                : 'Sorry you changed your mind!',
          ),
          actions: <Widget>[
            SimpleDialogOption(
              child: const Text('Dismiss'),
              onPressed: () {
                Navigator.of(context).pop();
              },
            )
          ],
        );
      },
    );
  },
);

Subscriptions (Experimental) #

The syntax for subscriptions is again similar to a query, however, this utilizes WebSockets and dart Streams to provide real-time updates from a server. Before subscriptions can be performed a global instance of socketClient needs to be initialized.

We are working on moving this into the same GraphQLProvider structure as the http client. Therefore this api might change in the near future.

socketClient = await SocketClient.connect('ws://coolserver.com/graphql');

Once the socketClient has been initialized it can be used by the Subscription Widget

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Subscription(
          operationName,
          query,
          variables: variables,
          builder: ({
            bool loading,
            dynamic payload,
            dynamic error,
          }) {
            if (payload != null) {
              return Text(payload['requestSubscription']['requestData']);
            } else {
              return Text('Data not found');
            }
          }
        ),
      )
    );
  }
}

GraphQL Consumer #

You can always access the client directly from the GraphQLProvider but to make it even easier you can also use them GraphQLConsumer widget.

  ...

  return GraphQLConsumer(
    builder: (GraphQLClient client) {
      // do something with the client

      return Container(
        child: Text('Hello world'),
      );
    },
  );

  ...

GraphQL Upload #

We support GraphQL Upload spec as proposed at https://github.com/jaydenseric/graphql-multipart-request-spec

mutation($files: [Upload!]!) {
  multipleUpload(files: $files) {
    id
    filename
    mimetype
    path
  }
}
import 'dart:io' show File;

// ...

String filePath = '/aboslute/path/to/file.ext';
final QueryResult r = await graphQLClientClient.mutate(
  MutationOptions(
    document: uploadMutation,
    variables: {
      'files': [File(filePath)],
    },
  )
);

Roadmap #

This is currently our roadmap, please feel free to request additions/changes.

FeatureProgress
Queries
Mutations
Subscriptions
Query polling
In memory cache
Offline cache sync
GraphQL pload
Optimistic results
Client state management🔜
Modularity🔜

See GitHub Releases.

[1.0.1-beta] - April 27 2019

We now have a (beta) stand-alone client!

For those who want to try it out, checkout the graphql/client.dart 1.0.1-beta.

[1.0.0+4] - April 23 2019

Fix dart 2.3 compilation issue @mateusfsilva

[1.0.0+3] - April 23 2019

Actually Fixes for some minor linting issues, as well as a stack overflow edgecase with complex cache structures

[1.0.0+2] - April 22 2019

[1.0.0+1] - April 21 2019

Most changes here are from @micimize in #199

Breaking changes #

  • Broke onCompleted signature because it didn't match apollo's and is only called when data is ready.
  • Moved _inMemoryCache to @protected data for testing/override purposes (important for OptimisticPatches
  • Updated the example to use optimism
  • adds a refetch argument to the Query builder

Fixes / Enhancements #

  • subscription and null variable fixes from @yunyu
  • many documentation fixes and additions From @mainawycliffe
  • disable polling with 0 interval @mainawycliffe
  • Added OptimisticCache and related attributes to QueryResult (optimistic, timestamp)
  • Added lazy_cache_map.dart for handling cyclical dereferences in the normalized cache
    • added CacheState for tracking optimism from the perspective of normalized cache entities
  • Added raw_operation_data.dart to consolidate base functionality
  • Added rebroadcastQueries to the QueryManager, for use post-update, which rebroadcasts all "safe" queries that can be with updated data from the cache
  • Added optimisticResult management to the QueryManager
  • Added optimisticResult to BaseOptions, and QueryOptions (it is added in runMutation for mutations)
  • Added optimistic attribute QueryResult itself for lifecycle management.

Docs #

  • LazyCacheMap usage and reasoning
  • Optimism section. differences between result.optimistic and LazyCacheMap.isOptimistic
  • update, onCompleted usage/existence
  • refetch usage/existence

[1.0.0-beta.1+1] - February 16 2019

We are finally in BETA. This means we're one step closer to our first stable release.

Thanks to all the contributes.

Support GraphQL Upload spec as proposed at https://github.com/jaydenseric/graphql-multipart-request-spec

What's changed? #

We have added a brand new Link that handles authentication. You can drop it in like so:

final HttpLink httpLink = HttpLink(
  uri: 'https://api.github.com/graphql',
);

final AuthLink authLink = AuthLink(
  getToken: () async => 'Bearer $YOUR_PERSONAL_ACCESS_TOKEN',
);

final Link link = authLink.concat(httpLink);

GraphQLClient client = GraphQLClient(
  cache: NormalizedInMemoryCache(
    dataIdFromObject: typenameDataIdFromObject,
  ),
  link: link,
);

The getToken function will be called right before each event gets passed to the next link. It set the Authorization header to the value returned by getToken and passes it under the header map to the context.

Breaking changes #

n/a

Fixes / Enhancements #

  • Fixed decouple mutation side effects from component (#114). @micimize
  • Fixed data == {} was always false, instead of data.isEmpty. @nesger
  • Added update(cache, result) attribute to Mutation. @micimize
  • Added NormalizationException to handle infinite dereference StackOverflow due to user error. @micimize
  • Added the GraphQL message type GQL_CONNECTION_KEEP_ALIVE, so it isn't interpreted as UnknownData anymore. @ArneSchulze
  • Added the brand ne AuthLink class. @HofmannZ
  • Update example to use NormalizedCache / test decoupling by replacing the Mutation while in flight. @micimize
  • Removed closed observable queries from QueryManager. @micimize

Docs #

  • Fixed typos. @xtian
  • Added MessageType constant GQL_CONNECTION_KEEP_ALIVE. @ArneSchulze
  • Added GraphQLSocketMessage class ConnectionKeepAlive. @ArneSchulze
  • Added Stream<ConnectionKeepAlive> to GraphQLSocket. @ArneSchulze
  • Updated the example to use the new AuthLink. @HofmannZ

[1.0.0-alpha.11] - October 28 2018

Breaking changes #

n/a

Fixes / Enhancements #

  • Added NormalizedInMemoryCache as a new cache option. @micimize
  • Fixed Mutation calling onCompleted for loading state. @rafaelring
  • Fix type annotations. @HofmannZ
  • Fixed http versions. @HofmannZ

Docs #

  • Added docs for the new NormalizedInMemoryCache option. @micimize
  • Added @rafaelring as a contributor. @HofmannZ

[1.0.0-alpha.10] - October 6 2018

Breaking changes #

n/a

Fixes / Enhancements #

  • Fixed Query variables not updating in the query. @micimize
  • Fixed Mutation widget's behavior to properly set loading status. @Igor1201

Docs #

  • Added @micimize as a contributor. @HofmannZ
  • Added @Igor1201 as a contributor. @HofmannZ

[1.0.0-alpha.9] - September 25 2018

Breaking changes #

n/a

Fixes / Enhancements #

  • Fixed connectivity errors not being thrown and streamed. @HofmannZ

Docs #

n/a

[1.0.0-alpha.8] - September 21 2018

Breaking changes #

n/a

Fixes / Enhancements #

  • Removed an unused class. @HofmannZ
  • Formatted the query manger. @HofmannZ
  • Handle charset encoding in responses @kolja-esders

Docs #

  • Added some inline docs to Query widget. @HofmannZ
  • Improved the inline docs of the client. @HofmannZ
  • Update the example. @HofmannZ

[1.0.0-alpha.7] - September 14 2018

Breaking changes #

n/a

Fixes / Enhancements #

  • Fixed a bug where getting the operation name was always returning null. @HofmannZ
  • Override the fetch policy if the default query option is used. @HofmannZ
  • Split up fetching and polling in the observable query. @HofmannZ
  • Check if the stream is closed, before adding a new event to it. @HofmannZ
  • Check if the variables have actually changed form or to null. @HofmannZ
  • Added a new getter to check if a query result has errors. @HofmannZ
  • Refactored the scheduler to only handle polling queries. @HofmannZ
  • Updated the mutation widget to use the new api in observable query. @HofmannZ
  • Resolve type cast exception when handling GraphQL errors. @kolja-esders @HofmannZ
  • Propagate GraphQL errors to caller instead of throwing network exception. @kolja-esders

Docs #

n/a

[1.0.0-alpha.6] - September 10 2018

Breaking changes #

n/a

Fixes / Enhancements #

  • Updated lint options in preparation for upcoming CI checks. @HofmannZ

Docs #

n/a

[1.0.0-alpha.5] - September 7 2018

Breaking changes #

n/a

Fixes / Enhancements #

  • Fixed a bug where the wrong key was selected from the context map. @HofmannZ
  • Fixed a scenario where the dispose method was calling the close method on the observableQuery class which might not have been initialised yet. @HofmannZ
  • Added the onComplete callback for the Mutation widget. @HofmannZ
  • Added the initPayload as an optional parameter for the connect method on the SocketClient class. @lordgreg

Docs #

  • Added an example of optionally overriding http options trough the context. @HofmannZ
  • Added @lordgreg as a contributor. @HofmannZ
  • Updated the example with explicit type casting. @HofmannZ
  • Updated the Mutation example with the new onComplete callback. @HofmannZ

[1.0.0-alpha.4] - September 4 2018

Breaking changes #

n/a

Fixes / Enhancements #

  • Always return something from the read method in the cache class. @HofmannZ
  • Only save to cache with certain fetch policies. @HofmannZ
  • Throw an error when no data from network with certain fetch policies. @HofmannZ
  • Added a document parser. @HofmannZ
  • Added operation name from document to the operation. @HofmannZ
  • Only create a new observable query if options have changed. @HofmannZ
  • Add context to the links. @HofmannZ
  • Parse context in the http link to update the config. @HofmannZ
  • Change the type of context from dynamic to Map<String, dynamic. @HofmannZ

Docs #

n/a

[1.0.0-alpha.3] - September 2 2018

Breaking changes #

n/a

Fixes / Enhancements #

  • Reverted changes to the required Dart version. @HofmannZ
  • Added missing return statsments. @HofmannZ

Docs #

n/a

[1.0.0-alpha.2] - September 2 2018

Breaking changes #

n/a

Fixes / Enhancements #

  • GraphQLClient now reads and writes data from the Cache based on the provided FetchPolicy option. @HofmannZ
  • Implemented caching for data from FetchResults. @HofmannZ
  • The library now tagets Dart version >=2.1.0-dev.0.0 <3.0.0 as recomended by Flutter 0.6.0. @HofmannZ
  • Removed the old client from the library. @HofmannZ

Docs #

  • Document the new API. @HofmannZ
  • Write an upgrade guide. @HofmannZ
  • Clean up the example. @HofmannZ

[1.0.0-alpha.1] - September 2 2018

Breaking changes #

  • Renamed Client to GraphQLClient to avoid name collision with other packages. @HofmannZ
  • Renamed GraphqlProvider to GraphQLProvider to align with new naming. @HofmannZ
  • Renamed GraphqlConsumer to GraphQLConsumer to align with new naming. @HofmannZ
  • Renamed GQLError to GraphQLError to align with new naming. @HofmannZ
  • GraphQLClient requires a Link to passed into the constructor. @HofmannZ
  • GraphQLClient no longer requires a endPoint or apiToken to be passed into the constructor. Instead you can provide it to the Link. @HofmannZ
  • The Query and Mutation widgets are now StreamBuilders, there the api did change slightly. @HofmannZ

Fixes / Enhancements #

  • Improved typing throughout the library. @HofmannZ
  • Queries are handled as streams of operations. @HofmannZ
  • Added the HttpLink to handle requests using http. @HofmannZ
  • HttpLink allows headers to be customised. @HofmannZ
  • The api allows contributors to write their own custom links. @HofmannZ

Docs #

  • Implement the new link system in the example. @HofmannZ

[0.9.3] - September 5 2018

Breaking changes #

n/a

Fixes / Enhancements #

  • Fix wrong typedef causing runtime type mismatch. @HofmannZ

Docs #

  • Update the reference to the next branch. @HofmannZ

[0.9.2] - 2 September 2018

Breaking changes #

n/a

Fixes / Enhancements #

  • Upgrade dependencies. @HofmannZ

Docs #

  • Added a refrence to our next major release. @HofmannZ

[0.9.1] - August 30 2018

Breaking changes #

n/a

Fixes / Enhancements #

  • Move test dependency to the dev section. @fabiocarneiro
  • Fix version resolving for test dependencies. @HofmannZ

Docs #

n/a

[0.9.0] - August 23 2018

Breaking changes #

n/a

Fixes / Enhancements #

  • Added error extensions support. @dustin-graham
  • Changed the mutation typedef to return a Future, allowing async/await. @HofmannZ
  • Fixed error handling when location is not provided. @adelcasse
  • Fixed a bug where the client might no longer be in the same context. @HofmannZ

Docs #

n/a

[0.8.0] - August 10 2018

Breaking changes #

n/a

Fixes / Enhancements #

  • Added basic error handeling for queries and mutations @mmadjer
  • Added missing export for the GraphqlConsumer widget @AleksandarFaraj

Docs #

n/a

[0.7.1] - August 3 2018

Breaking changes #

n/a

Fixes / Enhancements #

  • Code formatting @HofmannZ

Docs #

  • Updated the package description @HofmannZ

[0.7.0] - July 22 2018

Breaking changes #

n/a

Fixes / Enhancements #

  • Added support for subsciptions in the client. @cal-pratt
  • Added the Subscription widget. You can no direcly acces streams from Flutter. @cal-pratt

Docs #

  • Added instructions for adding subscripton to your poject. @cal-pratt
  • Updated the About this project section. @HofmannZ

[0.6.0] - July 19 2018

Breaking changes #

  • The library now requires your app to be wrapped with the GraphqlProvider widget. @HofmannZ
  • The global client variable is no longer available. Instead use the GraphqlConsumer widget. @HofmannZ

Fixes / Enhancements #

  • Added the GraphqlProvider widget. The client is now stored in an InheritedWidget, and can be accessed anywhere within the app. @HofmannZ
Client client = GraphqlProvider.of(context).value;
  • Added the GraphqlConsumer widget. For ease of use we added a widget that uses the same builder structure as the Query and Mutation widgets. @HofmannZ

Under the hood it access the client from the BuildContext.

  • Added the option to optionally provide the apiToken to the Client constructor. It is still possible to set the apiToken with setter method. @HofmannZ
  return new GraphqlConsumer(
    builder: (Client client) {
      // do something with the client

      return new Container();
    },
  );

Docs #

  • Added documentation for the new GraphqlProvider @HofmannZ
  • Added documentation for the new GraphqlConsumer @HofmannZ
  • Changed the setup instructions to include the new widgets @HofmannZ
  • Changed the example to include the new widgets @HofmannZ

[0.5.4] - July 17 2018

Breaking changes #

n/a

Fixes / Enhancements #

  • Query: changed Timer to Timer.periodic @eusdima
  • Minor logic tweak @eusdima
  • Use absolute paths in the library @HofmannZ

Docs #

  • Fix mutations example bug not updating star bool @cal-pratt

[0.5.3] - July 13 2018

Breaking changes #

n/a

Fixes / Enhancements #

  • Added polling timer as a variable for easy deletion on dispose
  • Fixed bug when Query timer is still active when the Query is disposed
  • Added instant query fetch when the query variables are updated

Docs #

n/a

[0.5.2] - July 11 2018

Breaking changes #

n/a

Fixes / Enhancements #

  • Fixed error when cache file is non-existent

Docs #

n/a

[0.5.1] - June 29 2018

Breaking changes #

n/a

Fixes / Enhancements #

  • Fixed json error parsing.

Docs #

n/a

[0.5.0] - June 25 2018

Breaking changes #

n/a

Fixes / Enhancements #

  • Introduced onCompleted callback for mutiations.
  • Excluded some config files from version control.

Docs #

  • Fixed typos in the readme.md.
  • The examples inculde an example of the onCompleted callback.

[0.4.1] - June 22 2018

Breaking changes #

n/a

Fixes / Enhancements #

n/a

Docs #

  • The examples now porperly reflect the changes to the library.

[0.4.0] - June 21 2018

Breaking changes #

  • The Client now requires a from of cache.
  • The name of the execute method on the Client class changed to query.

Fixes / Enhancements #

  • Implemented in-memory cache.
  • Write memory to file when in background.
  • Added provider widget to save and restore the in-memory cache.
  • Restructure the project.

Docs #

  • Update the README.md to refelct changes in the code.
  • update the example to refelct changes in the code.

[0.3.0] - June 16 2018

Breaking changes #

  • Changed data type to Map instaid of Object to be more explicit.

Fixes / Enhancements #

  • Cosmatic changes.

Docs #

  • Added a Flutter app example.
  • Fixed the example in README.md.
  • Added more badges.

[0.2.0] - June 15 2018

Breaking changes #

  • Changed query widget polling argument to pollInterval, following the react-apollo api.

Fixes / Enhancements #

  • Query polling is now optional.

Docs #

  • Updated the docs with the changes in api.

[0.1.0] - June 15 2018

My colleague and I created a simple implementation of a GraphQL Client for Flutter. (Many thanks to Eus Dima, for his work on the initial client.)

Breaking changes #

n/a

Fixes / Enhancements #

  • A client to connect to your GraphQL server.
  • A query widget to handle GraphQL queries.
  • A mutation widget to handle GraphQL mutations.
  • Simple support for query polling.

Docs #

  • Initial documentation.

example/README.md

Example App #

A new Flutter project.

Getting Started #

For help getting started with Flutter, view our online documentation.

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  graphql_flutter: ^2.1.0

2. Install it

You can install packages from the command line:

with Flutter:


$ flutter pub get

Alternatively, your editor might support flutter pub get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


import 'package:graphql_flutter/graphql_flutter.dart';
  
Popularity:
Describes how popular the package is relative to other packages. [more]
96
Health:
Code health derived from static analysis. [more]
42
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
100
Overall:
Weighted score of the above. [more]
80
Learn more about scoring.

We analyzed this package on Dec 11, 2019, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.7.0
  • pana: 0.13.1+4
  • Flutter: 1.12.13+hotfix.4

Health issues and suggestions

Fix lib/src/widgets/cache_provider.dart. (-57.81 points)

Analysis of lib/src/widgets/cache_provider.dart failed with 3 errors:

line 52 col 5: Missing case clause for 'detached'.

line 64 col 12: Case expressions must be constant.

line 64 col 30: The getter 'suspending' isn't defined for the class 'AppLifecycleState'.

Fix lib/src/widgets/graphql_provider.dart. (-0.50 points)

Analysis of lib/src/widgets/graphql_provider.dart reported 1 hint:

line 60 col 15: 'inheritFromWidgetOfExactType' is deprecated and shouldn't be used. Use dependOnInheritedWidgetOfExactType instead. This feature was deprecated after v1.12.1..

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.2.2 <3.0.0
flutter 0.0.0
graphql ^2.1.0 2.1.0 2.1.1-beta.5
meta ^1.1.6 1.1.8
path ^1.6.2 1.6.4
path_provider ^1.1.0 1.5.1
rxdart ^0.22.0 0.22.6 0.23.0-dev.3
Transitive dependencies
async 2.4.0
charcode 1.1.2
collection 1.14.11 1.14.12
convert 2.1.1
crypto 2.1.4
graphql_parser 1.1.4
http 0.12.0+2
http_parser 3.1.3
mime 0.9.6+3
platform 2.2.1
sky_engine 0.0.99
source_span 1.5.5
string_scanner 1.0.5
term_glyph 1.1.0
typed_data 1.1.6
uuid_enhanced 3.0.2
vector_math 2.0.8
websocket 0.0.5
Dev dependencies
flutter_test
mockito ^4.0.0
pedantic <=1.7.99 1.9.0
test ^1.5.3