flutter getx web sockets - stream data to be cascaded to provider and controller

346

Try using map for transforming Streams:

 @override
  Stream<dynamic> subscribe({
    String query,
    Map<String, dynamic> variables,
  }) {
    debugPrint('===->subscribe===');
    // it can be any stream here, http or file or image or media
    final Stream<GraphQLResponse<String>> operation = Amplify.API.subscribe(
      GraphQLRequest<String>(
        document: query,
        variables: variables,
      ),
      onEstablished: () {
        debugPrint(
          '===->subscribe onEstablished ===',
        );
      },
    );
    
    return operation.map((event) {
      return json.decode(event.data);
    });
  }

  // elsewhere

  final subscription = subscribe(
    query: 'some query', 
    variables: {},
  );

  subscription.listen(
    (jsonData) {
      debugPrint('===->subscription data $jsonData');
    },
    onError: (Object e) => debugPrint('Error in subscription stream: $e'),
  );
Share:
346
raaone7
Author by

raaone7

Updated on January 01, 2023

Comments

  • raaone7
    raaone7 over 1 year

    Objective is simple

    • flutter app makes a call to graphql api over websockets
    • app view calls the controller, controller calls the provider, provider calls the AWS appsync api over websockets or over HTTP api socket call
    • we receive a stream of data from appsync api or HTTP api socket call over websockets every now and then from backend
    • streams need to be cascaded back to provider , and then to controller (this is the critical step)
    • controller (not the provider) would update the obs or reactive variable, make the UI reflect the changes

    problem : data is recieved via websockets in the caller, but never passed back as stream to provider or controller to reflect the changes

    sample code

    actual caller orderdata.dart

      @override
      Stream<dynamic> subscribe({
        String query,
        Map<String, dynamic> variables,
      }) async* {
        debugPrint('===->subscribe===');
        // it can be any stream here, http or file or image or media
        final Stream<GraphQLResponse<String>> operation = Amplify.API.subscribe(
          GraphQLRequest<String>(
            document: query,
            variables: variables,
          ),
          onEstablished: () {
            debugPrint(
              '===->subscribe onEstablished ===',
            );
          },
        );
    
        operation.listen(
          (event) async* {
            final jsonData = json.decode(event.data.toString());
            debugPrint('===->subscription data $jsonData');
            yield jsonData;
          },
          onError: (Object e) => debugPrint('Error in subscription stream: $e'),
        );
      }
    

    in the provider orderprovider.dart

      Stream<Order> orderSubscription(String placeId) async* {
        debugPrint('===->=== $placeId');
        subscriptionResponseStream = orderData.subscribe(
          query: subscribeToMenuOrder,
          variables: {"place_id": placeId},
        );
    
        subscriptionResponseStream.listen((event) async* {
          debugPrint(
            "===->=== yielded $event",
          );
          yield event;
        });
        debugPrint('===->=== finished');
      }
    

    in the controller homecontroller.dart

      Future<void> getSubscriptionData(String placeId) async {
        debugPrint('===HomeController->getSubscriptionData===');
        OrderProvider().orderSubscription(placeId).listen(
              (data) {
                //this block is executed when data event is receivedby listener
                debugPrint('Data: $data');
                Get.snackbar('orderSubscription', data.toString());
              },
              onError: (err) {
                //this block is executed when error event is received by listener
                debugPrint('Error: $err');
              },
              cancelOnError:
                  false, //this decides if subscription is cancelled on error or not
              onDone: () {
                //this block is executed when done event is received by listener
                debugPrint('Done!');
              },
            );
      }
    

    homeview calls homecontroller