0

I'm using Express Graphql server with react native and Relay. My device does connects to the subscription but it does not subscribe to it. Here's my index.js on the server

const subscriptionServer = SubscriptionServer.create(
  {
    execute,
    subscribe,
    schema,
    onOperation: (message, params, webSocket) => {
      console.log(params)
      return params;
    },
    onConnect: () => {
      // My device does connects
      console.log("client connected")
    }
  },
  {
    server,
    path: '/subscriptions'
  },
);

app.use('/graphql', graphqlHTTP({
  schema,
  graphiql: true
}));

app.use('/graphiql', graphiqlExpress({
  endpointURL: '/graphql',
  subscriptionsEndpoint: `ws://127.0.0.1:8080/subscriptions`
}));

server.listen(PORT, ()=> {
  console.log("Groceries running on port " + PORT)
  console.log(
    `subscriptions is now running on ws://localhost:${PORT}/subscriptions'}`
  );
});

The resolver for subscription on the server, it was quite troublesome to figure out since everyone is using executable schema from apolloGraphql.

export default {
  type: OrderEdges,
  args: {
     ShopId: {type: GraphQLID},
  },
  subscribe: withFilter(() => pubsub.asyncIterator('orderConfirmed'), (payload, variables) => {
    console.log(payload)
    console.log(variables)
    return payload.orderConfirmed.node.ShopId == variables.ShopId;
  }),
}

Now the react-native client. My subscription setup with relay environment.

const setupSubscriptions = (config, variables, cacheConfig, observer) => {
  const query = config.text; //does console logs the query
  const subscriptionClient = new SubscriptionClient(`ws://192.168.0.100:8080/subscriptions`, {reconnect:true});
  subscriptionClient.request({query, variables}, (err, result) => {
    console.log(err) // doesn't get call inside the request method
    observer.onNext(data:result)
  })
}

My subscription method,

export default function() {
  const variables = {
    ShopId: shop.getShop()[0].id
  } 
  requestSubscription(
  environment,
  {
    subscription,
    variables,
    onCompleted: (res, err) => {
      console.log(res)
      console.log(err)
    },
    updater: (store) => {...},
    onError: error => console.error(error),
    onNext: (response) => {console.log(response)}
  });

}

the component where I'm calling to subscribe,

import subscription from '../../GraphQLQueries/subscriptions/orderConfirmed';

class OrdersBox extends React.Component {
  constructor(props) {
    super(props);
  }

  componentDidMount() {
    //initializing subscription
    orderSubscriptions();
  }

When the device starts the app, my device is connected to the web socket as I can see the console.log statement inside the onConnect method in SubscriptionServer. But when the payload is published after a mutation, the subscribe method doesn't get called. I can't seem to figure out what I'm doing wrong. Maybe it's some react-native specific config that I'm missing cuz everything seems to work fine when I test it on graphiql. I can't find any example of react-native and relay subscriptions used with express graphql.

note: Everything is working when I use subscription with graphiql. But not with react-native and relay.

Thanks in advance guys ....

Saud Punjwani
  • 477
  • 1
  • 4
  • 14

2 Answers2

0

I wasn't returning the subscriptionClient.request method. Adding a return statement solved the problem. You don't have to return when using subscribe method in subscriptions-transport-ws@0.8.3. But version 0.9.1 replaces the subscribe function with request which does require it to return.

Saud Punjwani
  • 477
  • 1
  • 4
  • 14
  • are you returning subscriptionClient.request({ query, variables }) or subscriptionClient.request({ query, variables }).subscribe({ .....}); – sushil bansal Nov 27 '17 at 22:02
  • const setupSubscriptions = (config, variables, cacheConfig, observer) => { const query = config.text; const subscriptionClient = new SubscriptionClient(`ws://192.168.10.3:8080/subscriptions`, {reconnect:true}); return subscriptionClient.request({query, variables}, (err, result) => { observer.onNext(data:result) }) } – Saud Punjwani Nov 28 '17 at 18:52
  • I think .subscribe is removed now. U just have to return subscriptionClient.request – Saud Punjwani Nov 28 '17 at 18:53
  • got it working. It is subscriptionClient.request(..).subscribe(..) – sushil bansal Nov 29 '17 at 13:52
  • which version of subscriptions-transport are you using? – Saud Punjwani Nov 29 '17 at 14:01
0

try:

function setupSubscription(config, variables, cacheConfig, observer) {
  const query = config.text;

  const subscriptionClient = new SubscriptionClient(websocketURL, {
    reconnect: true
  });

  const client = subscriptionClient.request({ query, variables }).subscribe({
    next: result => {
      observer.onNext({ data: result.data });
    },
    complete: () => {
      observer.onCompleted();
    },
    error: error => {
      observer.onError(error);
    }
  });

  return {
    dispose: client.unsubscribe
  };
}

subscriptions-transport-ws@0.9.1

Ng Thong
  • 104
  • 1
  • 6