Skip to content

Flutter 3.0.2 / graphql_flutter: 5.1.1-beta.3 | Subscription QueryResult returns null  #1162

@hamzablx195

Description

@hamzablx195

The definition for the GraphQL Client is integrated into the code. Just trying to hook up the Subscription widget as provided by graphQL flutter.

The Query and Mutations work fine with the graphql endpoint. This is a public endpoint. We don't have any authorisation headers.

With the Subscription operation, the value being returned is always null and it is not listening to any updates.

Package version: graphql_flutter: ^5.1.1-beta.3

To Reproduce
Sample Main file::

import 'package:flutter/material.dart';
      import 'package:graphql_flutter/graphql_flutter.dart';
      
      void main() async {
        await initHiveForFlutter();
        // Hive.
        runApp(const MyApp());
      }
      
      class MyApp extends StatefulWidget {
        const MyApp({Key? key}) : super(key: key);
      
        @override
        State<MyApp> createState() => _MyAppState();
      }
      
      class _MyAppState extends State<MyApp> {
        ValueNotifier<GraphQLClient>? gqlClient;
      
        @override
        void initState() {
          // TODO: implement initState
          super.initState();
          gqlClient = ValueNotifier(
            initializeGQL(),
          );
        }
      
        @override
        Widget build(BuildContext context) {
          // initializeGQL();
      
          return GraphQLProvider(
            client: gqlClient,
            child: MaterialApp(
              title: 'Flutter Demo',
              theme: ThemeData(
                primarySwatch: Colors.blue,
              ),
              home: const MyHomePage(
                title: 'Flutter Demo Home Page',
              ),
            ),
          );
        }
      
        GraphQLClient initializeGQL() {
          String apiLink = 'https://idh66.sse.codesandbox.io/graphql';
          String wssLink = 'wss://idh66.sse.codesandbox.io/graphql';
          HttpLink link = HttpLink(apiLink);
      
          var wsLink = WebSocketLink(
            wssLink,
            config: const SocketClientConfig(
              inactivityTimeout: Duration(seconds: 5),
            ),
            subProtocol: SocketSubProtocol.graphqlWs,
          );
          final Link linkSplitted = link.split(
            (request) => request.isSubscription,
            wsLink,
            link,
          );
          Policies pp = Policies(
            fetch: FetchPolicy.networkOnly,
            error: ErrorPolicy.all,
            cacheReread: CacheRereadPolicy.mergeOptimistic,
          );
          print('''
      
          -------------------------------------------------------------------------------
      
          ''');
          print(linkSplitted);
          return GraphQLClient(
            link: linkSplitted,
            cache: GraphQLCache(store: HiveStore()),
            alwaysRebroadcast: true,
            defaultPolicies: DefaultPolicies(
              subscribe: pp,
              query: pp,
              mutate: pp,
            ),
          );
        }
      }
      
      class MyHomePage extends StatefulWidget {
        const MyHomePage({Key? key, required this.title}) : super(key: key);
      
        final String title;
      
        @override
        State<MyHomePage> createState() => _MyHomePageState();
      }
      
      class _MyHomePageState extends State<MyHomePage> {
        SubscriptionOptions? ops;
      
        final String readNumber = """
        query Query {
        currentNumber
      }
      """;
      
        final subscriptionDocument = gql('''
      subscription Subscription {
        numberIncremented
      }''');
        @override
        void initState() {
          super.initState();
      
          setSubscription();
        }
      
        setSubscription() {
          ops = SubscriptionOptions(
            fetchPolicy: FetchPolicy.networkOnly,
            errorPolicy: ErrorPolicy.all,
            document: subscriptionDocument,
          );
        }
      
        @override
        Widget build(BuildContext context) {
          return Scaffold(
            appBar: AppBar(
              title: Text(widget.title),
            ),
            body: Subscription(
                options: ops!,
                builder: (snap) {
                  return Column(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: [
                      const Text('hello from subscription'),
                      Text('Subscription Data: == ${snap.data.toString()}'),
                      Query(
                        options: QueryOptions(
                          document: gql(
                            readNumber,
                          ), // this is the query string you just created
      
                          pollInterval: const Duration(seconds: 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.hasException) {
                            return Text(result.exception.toString());
                          }
      
                          if (result.isLoading) {
                            return const Text('Loading');
                          }
      
                          return Text(result.data.toString());
                        },
                      ),
                    ],
                  );
                }),
          );
        }
      }

The Subscription operation keeps returning null value.

Expected behavior
A listener to work properly as it does with the exposed apollo client on the server.

device / execution context
Tested on Android physical and emulated devices.

Other useful/optional fields

Please fill or delete these sections if you don't fill them in

Query Result Response as received by the subscription.

Stacktrace:
{
QueryResult(source: QueryResultSource.network, data: {numberIncremented: null}, context: Context({ResponseExtensions: Instance of 'ResponseExtensions', HttpLinkResponseContext: Instance of 'HttpLinkResponseContext'}), exception: null, timestamp: 2022-06-16 02:27:51.565108)}
  • What backend are you trying to use?
    We have a node express instance configured with graphql and ws on AWS ec2.

  • If you have a network issue, does your operation work with GraphiQL?
    We tried an implementation based on graphiQL and that worked with our Subscription client.

Metadata

Metadata

Labels

🐛 bugSomething isn't working⚡ websocketWeb Socket RelatedPriority: HighHigh priority to include it inside next release

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions