Adding GraphQL to Flutter Mobile App

Adding GraphQL to Flutter Mobile App

The next update to the GameScore mobile application is to add GraphQL support and use polling for getting the GameScore data. This mobile applications is built upon Oracle's MERN Stack. This is Oracle's full stack for Web and Mobile development based on Parse Platform. It is the latest in a series of posts documenting how to build a mobile application in flutter and run it using Oracle's MERN Stack. The previous posts are:

  1. First Flutter Mobile App
  2. User Authentication with Flutter/Parse Stack
  3. Adding a Bottom Nav Bar to a Flutter App
  4. User Sessions in Oracle MBaaS Stack

but there was a hack where the list GameScore screen needed to be polled to get newly added data, using the dreaded Refresh button

Article content


By using Flutter's GraphQL support, the query can be run on a poll interval. The Refresh button can be removed and the buffer will be refreshed every 10 seconds.

Main.Dart Changes

First thing, create a GraphQL client and wrap it in a ValueNotifier. The GraphQLClient takes 2 parameters in this simple example, the endpoint (httpLink) and a GraphQLCache.

  client = ValueNotifier(
    GraphQLClient(
      link: httpLink,
      // The default store is the InMemoryStore, which does NOT persist to disk
      // cache: GraphQLCache(store: HiveStore()),
      cache: GraphQLCache(store: InMemoryStore()),
    ),
  );        

The httpLink is constructed with the graphql endpoint from Parse Server.

  final HttpLink httpLink = HttpLink(
    'http://129.93.180.71/graphql',
    defaultHeaders: <String, String>{
      'X-Parse-Application-Id': keyApplicationId,
      'X-Parse-Master-Key': '4O5iFCDAdepqgN8nX556DOlQFQaDj0FxQTexinUJ'
    },
  );        

In Flutter, a ValueNotifier is not specific to GraphQL but rather a part of Flutter's broader framework for managing state and notifying widget updates. It's a class provided by the Flutter framework that allows you to create a mutable value that can be observed by widgets. A ValueNotifier is an object that holds a single value and notifies its listeners whenever that value changes. It's a simple way to manage and propagate changes in your app's state.

Now, In main.dart build, wrap the GraphQLClient in a GraphQLProvider. We also wrap GoRouter within GraphQLProvider so that the functionality provided by GoRouter is carried forward

  Widget build(BuildContext context) {
    // Wrap GoRouter with GraphQLProvider
    return GraphQLProvider(client: client, child: goRouterWidget());
  }

  Widget goRouterWidget() {
    return MaterialApp.router(
      routerConfig: _router,
    );        

In Flutter, the GraphQLProvider is a component provided by the graphql_flutter package, which is commonly used to integrate GraphQL into your Flutter applications. The primary purpose of the GraphQLProvider is to configure and provide a GraphQL client to the widget tree so that you can perform GraphQL queries and mutations within your Flutter app. In this example, the GraphQLProvider makes the configured GraphQL client available to all widgets in the app's widget tree. You can then use this client to perform GraphQL queries and mutations within your Flutter app. By using the GraphQLProvider, you ensure that your GraphQL client is properly configured and accessible to the widgets that need it, simplifying the integration of GraphQL into your Flutter application.

main.dart changes


Getdata.Dart Changes

This widget is a total rewrite from a FutureBuilder to a GraphQL Query. A FutureBuilder widget is used to build a widget tree based on the result of a Future computation. It's particularly useful when you need to perform an asynchronous operation, such as fetching data from an API, and update your UI when the operation is complete. A GraphQL query is a better option for this use case of retrieving all the data because it offers polling and pagination. First, define the GraphQL query that gets all the GameScore documents. Using GraphQL with Oracle's MERN Stack discusses the semantics of a query like getALLGameScores below

String getAllGameScores = '''
query getSomeGameScores{
  gameScores {
    pageInfo {
      hasNextPage
      hasPreviousPage
      startCursor
      endCursor
    }
    count
    edges {
      cursor
      node {
        id
        playerName
        score
        cheatmode
      }
    }
  }
}
''';        

And run it using the Query class. In Flutter's GraphQL package, the Query class is used to define and perform GraphQL queries. Set the pollInterval to 10 seconds.

Query(
   options: QueryOptions(
     document: gql(getAllGameScores),
     pollInterval: const Duration(seconds: 10),
   ),
   builder: (QueryResult result,
       {VoidCallback? refetch, FetchMore? fetchMore}) {
     if (result.hasException) {
       print(result.exception.toString());
       return Text(result.exception.toString());
     }

     if (result.isLoading) {
       return const CircularProgressIndicator();
     }

     var edges = result.data!["gameScores"]["edges"];
        

And use the results in a ListView

return ListView.builder(
  scrollDirection: Axis.vertical,
  shrinkWrap: true,
  physics: const ClampingScrollPhysics(),
  itemCount: result.data!["gameScores"]["count"],
  itemBuilder: (context, index) {
    return Card(
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: <Widget>[
          ListTile(
            leading: const Icon(Icons.scoreboard),
            title: Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                const Text(
                  "Player Name:",
                  style: TextStyle(fontWeight: FontWeight.bold),
                ),
                Text(edges[index]["node"]["playerName"]),
                const Text(
                  "Score:",
                  style: TextStyle(fontWeight: FontWeight.bold),
                 ),
                Text(
                  edges[index]["node"]["score"].toString(),
                ),
              ],
            ),
            subtitle: Text(
       "CheatMode Enabled:  ${edges[index]["node"]["cheatmode"]}"),
          ),
        ],
      ),
    );
  },
);
        

And now there is a screen that lists all GameScore documents without having to use a"Refresh" button. It polls every 10 seconds to refresh the data.

Article content


GetData.dart

Summary

This post demonstrated how to run GraphQL from a Flutter mobile application using the Oracle's MERN Stack. It configured GraphQL in Main.dart and made the functionality available to all widgets in the application.

A better way to do it would be to using GraphQL Subscriptions? Or demonstrate Pagination support? Please let me know what you would like to see in a future blog post.



To view or add a comment, sign in

More articles by Doug Drechsel

Insights from the community

Others also viewed

Explore topics