Apollo Subscription Resolver Never Activates?

My component is calling a subscription query, but for some reason the subscription resolver isn’t being accessed: a breakpoint in it is never activated. And yet on the client I get the GraphQL subscription error:

“Subscription must return Async Iterable. Received: undefined”

What could be causing this?

Thanks in advance to all for any info!

SUBSCRIPTION QUERY

const IM_SUBSCRIPTION_QUERY = gql`
      subscription getIMsViaSubscription($fromID: String!, $toID: String!){
          IMAdded(fromID:$fromID, toID: $toID){
            id,
            fromID,
            toID,
            msgText,
            myUserData{
                id,
                name_first,
                name_last,
                picture_large,
                picture_medium,
                picture_thumbnail
                my_category
            }
          }
        } 
`;

RESOLVER

Subscription: {
    IMAdded(IMThatWasAdded) {
        debugger; <== IS NEVER ACTIVATED
        subscribe: withFilter(() => SubscriptionServer.pubsub.asyncIterator(IM_ADDED_CHANNEL), (newIM, args) => {
            const callIsFromMsgFoldersComponent = args.toID == 0;
            var result;
            if (callIsFromMsgFoldersComponent){
                result = (newIM.fromID === args.fromID || newIM.toID === args.fromID);
            } else {
                result = ((newIM.fromID === args.fromID && newIM.toID === args.toID) || (newIM.fromID === args.toID && newIM.toID === args.fromID));
            }
            return result;
        })

COMPONENT

const withDataAndSubscription = graphql(GETIMS_QUERY, {
    options({toID}) {
        console.log(GETIMS_QUERY);
        const fromID = Meteor.userId();
        return {
            fetchPolicy: 'cache-and-network',
            variables: {fromID: `${fromID}`, toID: `${toID}`}
        };
    }
    ,
    props: props => {
        debugger;
        return {
            loading: props.data.loading,
            instant_message: props.data.instant_message,
            subscribeToMore: props.data.subscribeToMore,
            subscribeToNewIMs: params => {
                debugger;  <==IS ACTIVATED AS EXPECTED
                console.log(IM_SUBSCRIPTION_QUERY); <==IS OKAY
                const fromID = Meteor.userId();
                const toID = params.toID;
                return props.data.subscribeToMore({
                    document: IM_SUBSCRIPTION_QUERY,
                    variables: {fromID: `${fromID}`, toID: `${toID}`},
                    updateQuery: (previousResult, {subscriptionData}) => {
                        if (!subscriptionData.data) {
                            return previousResult;
                        }
                        const newMsg = subscriptionData.data.createIM;
                        return update(previousResult, {
                            instant_message: {
                                $push: [newMsg],
                            },
                        });
                    }
                });
            }
        };
    },
})
;

Server-side setup, and mutation/subscription resolvers have changed quite a bit since the code in my post, which was based on Apollo libs from late last year. Here is code that works with current Apollo libs, based on this tutorial:

SERVER SETUP

    import express from 'express';
    import { graphqlExpress, graphiqlExpress } from 'graphql-server-express';
    import bodyParser from 'body-parser';
    import  cors  from 'cors';
    import { execute, subscribe } from 'graphql';
    import { createServer } from 'http';
    import { SubscriptionServer } from 'subscriptions-transport-ws';
    
    import schema from '/imports/api/schema';
    
    //SET UP APOLLO QUERY / MUTATIONS / PUBSUB
    const METEOR_PORT = 3000;
    const GRAPHQL_PORT = 4000;
    const server = express();
    
    server.use('*', cors({ origin: 'http://localhost:${METEOR_PORT}' }));
    
    server.use('/graphql', bodyParser.json(), graphqlExpress({
        schema
    }));
    
    server.use('/graphiql', graphiqlExpress({
        endpointURL: '/graphql',
        subscriptionsEndpoint: `ws://localhost:${GRAPHQL_PORT}/subscriptions`
    }));
    
    // Wrap the Express server
    const ws = createServer(server);
    ws.listen(GRAPHQL_PORT, () => {
        console.log(`GraphQL Server is now running on http://localhost:${GRAPHQL_PORT}`);
        // Set up the WebSocket for handling GraphQL subscriptions
        new SubscriptionServer({
            execute,
            subscribe,
            schema
        }, {
            server: ws,
            path: '/subscriptions',
        });
    });
    //END OF SET UP APOLLO PUBSUB

MUTATION RESOLVER

       Mutation: {
            createIM(root, args, context) {
                var associatedUsers = [];
                associatedUsers.push(args.fromID);
                associatedUsers.push(args.toID);
                var IDofNewIM;
    
                return Promise.resolve()
                    .then(() => {
                        const newIM = connectors.IMs.create(args);
                        return newIM;
                    })
                    .then(IMAdded => {
                        // publish subscription notification
                        pubsub.publish(IM_ADDED_CHANNEL, { IMAdded, args});
                        return IMAdded;
                    })
                    .catch((err)=> {
                        console.log(err);
                    });
            },

SUBSCRIPTION RESOLVER

    IMAdded: {
        subscribe: withFilter(
            () => pubsub.asyncIterator(IM_ADDED_CHANNEL),
            (IMAdded, args) => {
                IMAdded = IMAdded.IMAdded;
                var result = ((IMAdded.fromID === args.fromID && IMAdded.toID === args.toID) || (IMAdded.fromID === args.toID && IMAdded.toID === args.fromID));
                return result;
            }
        )
    },
1 Like