I am creating a subscription with GraphQL, and I need to consume that subscription with Flutter, but I don't know how to do that, the thing that I need is something like a UI component that would be tied to a subscription and it will be automatically refreshed.
I will appreciate any feedback.
In the main. dart file, change the MyApp widget from a StatelessWidget to a StatefulWidget . To connect our Flutter app to the GraphQL server, we need to create a GraphQLClient , which requires a Link and a GraphQLCache . The instance of GraphQLClient is passed to a ValueNotifier .
You just need to make an HTTP request from the Flutter app, then use the returned data to set up the UI and display them. The new graphql_flutter plugin provides APIs and widgets that enable you to fetch and use data from a GraphQL backend with ease.
What are GraphQL Subscriptions? Subscriptions are a GraphQL feature allowing the server to send data to its clients when a specific event happens. Subscriptions are usually implemented with WebSockets, where the server holds a steady connection to the client.
GraphQL subscriptions are made majorly to listen to when data is created on the server, when a data is updated, when a data is deleted, and when a data is read via query. The event to emitted is dependent on what the dev wants. The events are pushed from the server to the subscribing clients.
My GraphqlServer runs a subscription named getLogs
which returns the log information in the following format.
{
"data": {
"getLogs": {
"timeStamp": "18:09:24",
"logLevel": "DEBUG",
"file": "logger.py",
"function": "init",
"line": "1",
"message": "Hello from logger.py"
}
}
}
If you are like me who wants to use only the GraphQL Client directly, then following sample could help.
import 'package:graphql/client.dart';
import 'package:graphql/internal.dart';
import 'package:flutter/material.dart';
import 'dart:async';
class LogPuller extends StatefulWidget {
static final WebSocketLink _webSocketLink = WebSocketLink(
url: 'ws://localhost:8000/graphql/',
config: SocketClientConfig(
autoReconnect: true,
),
);
static final Link _link = _webSocketLink;
@override
_LogPullerState createState() => _LogPullerState();
}
class _LogPullerState extends State<LogPuller> {
final GraphQLClient _client = GraphQLClient(
link: LogPuller._link,
cache: InMemoryCache(),
);
// the subscription query should be of the following format. Note how the 'GetMyLogs' is used as the operation name below.
final String subscribeQuery = '''
subscription GetMyLogs{
getLogs{
timeStamp
logLevel
file
function
line
message
}
}
''';
Operation operation;
Stream<FetchResult> _logStream;
@override
void initState() {
super.initState();
// note operation name is important. If not provided the stream subscription fails after first pull.
operation = Operation(document: subscribeQuery, operationName: 'GetMyLogs');
_logStream = _client.subscribe(operation);
}
@override
Widget build(BuildContext context) {
return StreamBuilder(
stream: _logStream,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(
child: Container(
child: CircularProgressIndicator(
strokeWidth: 1.0,
),
),
);
}
if (snapshot.hasData) {
return Center(
child: Text(
snapshot.data.data['getLogs']
['message'], // This will change according to you needs.
),
);
}
return Container();
},
);
}
}
As I am using a StreamBuilder to build the widget it will take care of closing the stream. If this is not the case for you, stream.listen()
method will return a StreamSubscription<FetchResult>
object which you can call the cancel()
method which can be done inside dispose()
method of a stateful widget or any such method for a standalone Dart
client.
You can check the next library https://github.com/zino-app/graphql-flutter
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With