Subscription not working with Apollo Client 2


#1

Using apollo subscription in my react-based app, and noticed that the subscription didn’t work. Working off this example: https://github.com/graphcool-examples/react-graphql/blob/master/subscriptions-with-apollo-worldchat/src/components/WorldChat.js#L114-L156

subscribeToMore shows the following error in the console:

[Exception: TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them at Function.remoteFunction (<anonymous>:2:14)]

Code:

if (!nextProps.data.loading && nextProps.data.user) {
  const { user } = nextProps.data
  this.userSubscription = nextProps.data.subscribeToMore({
    document: gql`
      subscription($userId: ID!) {
        User(filter: {
          mutation_in: [UPDATED]
          updatedFields_contains_some: ["nameFirst", "nameLast"]
          node: { id: $userId }
        }) {
          mutation
          updatedFields
          node {
            id
            email
            nameFirst
            nameLast
          }
        }
      }
    `,
    variables: { userId: user.id },
    updateQuery: (previousState, { subscriptionData, variables }) => {
      const { mutation, updatedFields } = subscriptionData.data.User
      console.log('Subscription: ' + mutation + '; updated fields: ' + updatedFields[0])
      nextProps.refetch()
    },
    onError: (err) => console.error(err)
  })
}

Utilizing the following packages:

“apollo-cache-inmemory”: “^1.1.4”,
“apollo-client”: “^2.0.4”,
“apollo-link”: “^1.0.7”,
“apollo-link-http”: “^1.3.2”,
“apollo-link-ws”: “^1.0.4”,
“apollo-utilities”: “^1.0.3”

Apollo Client 2.0 is set up like this:

const httpLink = new HttpLink({ uri: 'https://api.graph.cool/simple/v1/__PROJECT_ID__' })
const wsLink = new WebSocketLink({
  uri: 'wss://subscriptions.graph.cool/v1/__PROJECT_ID__',
  options: { reconnect: true }
})
const link = split(
  ({ query }) => {
    const { kind, operation } = getMainDefinition(query)
    return kind === 'OperationDefinition' && operation === 'subscription'
  },
  wsLink,
  httpLink
)
const middlewareLink = new ApolloLink((operation, forward) => {
  const token = window.localStorage.getItem('MyDemoApp:login')
  const authorizationHeader = token ? `Bearer ${token}` : null
  operation.setContext({ headers: { authorization: authorizationHeader } })
  return forward(operation)
})
const httpLinkWithAuthToken = middlewareLink.concat(link)

// Apollo Client
const client = new ApolloClient({
  link: httpLinkWithAuthToken,
  // eslint-disable-next-line
  cache: new InMemoryCache().restore(window.__APOLLO_STATE__)
})

Also tried this approach, to no avail (same error response in the console): https://www.apollographql.com/docs/react/features/subscriptions.html#subscribe-to-more


#2

Solved.

Apparently, I needed to specify the precise web socket link using Apollo Client @2.0:

const wsLink = new WebSocketLink({
  uri: 'wss://subscriptions.us-west-2.graph.cool/v1/__PROJECT_ID__',
  options: { reconnect: true }
})

Instead of this:

const wsLink = new WebSocketLink({
  uri: 'wss://subscriptions.graph.cool/v1/__PROJECT_ID__',
  options: { reconnect: true }
})

#3

Is this still the case? It doesn’t find my server with that URL structure.


#4

When you use the command graphcool-framework info in the CLI, it’ll show you which URL to use.


#5

I have tried all solutions for this issue, Nothing is working for me.

import { ApolloClient } from 'apollo-client';
import { split } from 'apollo-link';
import { createHttpLink } from 'apollo-link-http';
import { WebSocketLink } from 'apollo-link-ws';
import { setContext } from 'apollo-link-context';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { getMainDefinition } from 'apollo-utilities';

const Config = require('../../Config/AppConfig');

const httpLink = createHttpLink({ uri: Config.default.graphqlUri });
const token = `Bearer ${Config.default.token}`;

const wsLink = new WebSocketLink({
    uri: Config.default.subcriptionUri,
    options: { reconnect: true, timeout: 20000 },
    connectionParams: { Authorization: token, }
});

const authLink = setContext((_, { headers }) => (
    {
        headers: {
            ...headers,
            authorization: token,
        }
    }
));

const link = split(
    // split based on operation type
    ({ query }) => {
        const { kind, operation } = getMainDefinition(query);
        return kind === 'OperationDefinition' && operation === 'subscription';
    },
    wsLink,
    authLink.concat(httpLink),
);

export const client = new ApolloClient({
    link,
    cache: new InMemoryCache().restore(window.__APOLLO_STATE__)
});

componentWillReceiveProps(nextProps) {
    if (!nextProps.data.loading) {
      console.log('working');
      // Check for existing subscription
      if (this.unsubscribe) {
        // Check if props have changed and, if necessary, stop the subscription
        if (this.props.subscriptionParam !== nextProps.subscriptionParam) {
          this.unsubscribe();
        } else {
          return;
        }
      }

      // Subscribe
      this.unsubscribe = nextProps.data.subscribeToMore({
        document: ChatQuery.default.SubscribeToMessages,
        variables: {
          id: currentid
        },
        updateQuery: (previousResult, { subscriptionData, variables }) => {
          // Perform updates on previousResult with subscriptionData
          console.log('called by Server');
          return previousResult;
        }
      });
    }
  }

Can anyone tell me where i am going wrong…:disappointed::disappointed::disappointed:

package.json

"apollo-client": "^2.2.0",
"apollo-client-preset": "^1.0.6",
"apollo-link": "^1.0.7",
"apollo-link-context": "^1.0.3",
"apollo-link-error": "^1.0.5",
"apollo-link-http": "^1.3.2",
"apollo-link-ws": "^1.0.4",
"apollo-utilities": "^1.0.4",
"subscriptions-transport-ws": "^0.9.5"
"react-apollo": "^2.0.4",