Here is my problem, in my react app whenever a order is created I want to get a Subscription for that order called orderNotification,
setup in order resolver:
  Subscription: {
        orderNotification: {
            subscribe: (_, __, { pubsub }) => pubsub.asyncIterator(ORDER_NOTIFICATION)
        }
    }
mutation:
Mutation: {
        async createOrder(_, { MakeOrderInput: { state, message, products, total } }, context) {
            try {
                const userAuth = isAuth(context);
                const pubsub = context.pubsub;
                const newOrder = new Order({
                    state,
                    username: userAuth.username,
                    user: userAuth.id,
                    createdAt: new Date().toISOString(),
                    total,
                    message,
                    products,
                    userAddress: userAuth.address,
                });
           
                const index = products.findIndex(x => x.cost === 0);
                if (index != -1) {
                    const u = await User.findById({ _id: userAuth.id });
                    await User.findByIdAndUpdate({ _id: userAuth.id }, { points: u.points - 20 }, (err, data) => {
                        if (err) {
                            console.log(err)
                        } else {
                            console.log('fatto')
                        }
                    });
                }
                const order = await newOrder.save();
                pubsub.publish(ORDER_NOTIFICATION, {
                    orderNotification: order
                });
                return order;
            } catch (err) {
                // throw new Error(err);
                console.log(err)
            }
        },
all works fine in graphql Playground but when I have to get and show the results in my component the returned data is null:
import React from 'react'
import gql from 'graphql-tag';
import { useSubscription } from '@apollo/client';
import { Box } from 'grommet'
function SubscriptionOrder() {
    const { data, loading, error } = useSubscription(SUBSCRIPTION_USER_ORDER, {
        onSubscriptionData: (d) => console.log(d),
        onSubscriptionComplete: (da) => console.log(da)
    });
    // return null
    // console.log(data)
    return (
        <>
            <Box style={{ marginTop: '96px' }}>
                {data && data.orderNotification ? (
                    <h1>hi: {data.orderNotification.username}</h1>
                ) : (
                        <h1>NO DATA</h1>
                    )
                }
            </Box>
        </>
    )
};
const SUBSCRIPTION_USER_ORDER = gql`
  subscription orderNotification{
    orderNotification {
        username
    }
  }
`;
export default SubscriptionOrder;
so considering that in playground works the error may be in my ApolloClient links configuration:
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import { ApolloClient } from 'apollo-client';
import { ApolloProvider } from '@apollo/react-hooks';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { HttpLink } from 'apollo-link-http';
import { onError } from 'apollo-link-error';
import { ApolloLink, Observable, split } from 'apollo-link';
import { WebSocketLink } from 'apollo-link-ws';
import { getMainDefinition } from 'apollo-utilities';
import { TokenRefreshLink } from "apollo-link-token-refresh";
import jwtDecode from "jwt-decode";
import { getAccessToken, setAccessToken } from './accessToken';
import dotenv from 'dotenv/config.js'
const cache = new InMemoryCache({});
const httpLink = new HttpLink({
  uri: process.env.NODE_ENV === 'development' ? `${process.env.REACT_APP_SERVER_DEV}/graphql` : `${process.env.REACT_APP_SERVER_PRODUCTION}/graphql`,
  credentials: "include",
});
const wsLink = new WebSocketLink({
  uri: process.env.NODE_ENV === 'development' ? `ws://${process.env.REACT_APP_SERVER_DEV_WS}/graphql` : `ws://${process.env.REACT_APP_SERVER_PRODUCTION_WS}/graphql`,
  options: {
    reconnect: true,
    lazy: true,
    inactivityTimeout: 1000,
  },
  connectionCallback: err => {
    if (err) {
      console.log('Error Connecting to Subscriptions Server', err);
    }
  }
});
const splitLink = split(
  ({ query }) => {
    const { kind, operation } = getMainDefinition(query);
    return kind === "OperationDefinition" && operation === "subscriptions";
  },
  wsLink,
  httpLink
);
const requestLink = new ApolloLink(
  (operation, forward) =>
    new Observable(observer => {
      let handle;
      Promise.resolve(operation)
        .then(operation => {
          const accessToken = getAccessToken();
          if (accessToken) {
            operation.setContext({
              headers: {
                authorization: `Bearer ${accessToken}`
              },
              fetchOptions: {
                credentials: 'include'
              }
            });
          }
        })
        .then(() => {
          handle = forward(operation).subscribe({
            next: observer.next.bind(observer),
            error: observer.error.bind(observer),
            complete: observer.complete.bind(observer)
          });
        })
        .catch(observer.error.bind(observer));
      return () => {
        if (handle) handle.unsubscribe();
      };
    })
);
const client = new ApolloClient({
  link: ApolloLink.from([
    new TokenRefreshLink({
      accessTokenField: "accessToken",
      isTokenValidOrUndefined: () => {
        const token = getAccessToken();
        if (!token) {
          return true;
        }
        try {
          const { exp } = jwtDecode(token);
          if (Date.now() >= exp * 1000) {
            return false;
          } else {
            return true;
          }
        } catch {
          return false;
        }
      },
      fetchAccessToken: () => {
        return fetch(process.env.NODE_ENV === 'development' ? `${process.env.REACT_APP_SERVER_DEV}/refresh_token` : `${process.env.REACT_APP_SERVER_PRODUCTION}/refresh_token`, {
          method: "POST",
          credentials: "include"
        });
      },
      handleFetch: accessToken => {
        setAccessToken(accessToken);
      },
      handleError: err => {
        console.warn("Your refresh token is invalid. Try to relogin");
        console.error(err);
      }
    }),
    onError(({ graphQLErrors, networkError }) => {
      console.log(graphQLErrors);
      console.log(networkError);
    }),
    requestLink,
    splitLink,
  ]),
  cache,
  connectToDevTools: true,
  credentials: 'include',
});
ReactDOM.render(
  <React.StrictMode>
    <ApolloProvider client={client}>
      <App />
    </ApolloProvider>
  </React.StrictMode >,
  document.getElementById('root')
);
here is my server:
import { PubSub } from 'graphql-subscriptions';
const pubsub = new PubSub();
const server = new ApolloServer({
    typeDefs,
    resolvers,
    context: ({ req, res }) => ({ req, res, pubsub }),
    introspection: true,
    cors: corsOptions,
});
server.applyMiddleware({ app, cors: false });
const httpServer = http.createServer(app);
server.installSubscriptionHandlers(httpServer);
httpServer.listen(PORT, () => {
    console.log(`🚀 Server ready at http://localhost:${PORT}${server.graphqlPath}`)
    console.log(`🚀 Subscriptions ready at ws://localhost:${PORT}${server.subscriptionsPath}`)
})
resolve the payload in the subscription with
 Subscription: {
        orderNotification: {
            subscribe: (_, __, { pubsub }) => pubsub.asyncIterator(ORDER_NOTIFICATION),
             resolve: (payload) => {
                   return payload;
             },
        }
    }
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