2

So, I'm having an issue when attempting to create an Apollo/GraphCool subscription, which is throwing up the following error message:

[React Transform HMR] There was an error updating C:/Users/d0475/Documents/Projects/learn-redux-graphql/client/components/Comments.js:
(anonymous) @ index.js:59
hotApply @ bootstrap ac9bfc0…:514
cb @ process-update.js:52
hotUpdateDownloaded @ bootstrap ac9bfc0…:311
hotAddUpdateChunk @ bootstrap ac9bfc0…:283
webpackHotUpdateCallback @ bootstrap ac9bfc0…:4
(anonymous) @ 0.92fd6f4….hot-update.js:1
index.js:60 Error: ReactClassInterface: You are attempting to define `constructor` on your component more than once. This conflict may be due to a mixin.
    at invariant (invariant.js:39)
    at validateMethodOverride (ReactClass.js:384)
    at mixSpecIntoComponent (ReactClass.js:420)
    at Object.createClass (ReactClass.js:726)
    at Object.<anonymous> (Comments.js?32c0:17)
    at Object.748 (0.92fd6f4….hot-update.js:207)
    at __webpack_require__ (bootstrap ac9bfc0…:555)
    at Object.hotApply [as apply] (bootstrap ac9bfc0…:510)
    at cb (process-update.js:52)
    at hotUpdateDownloaded (bootstrap ac9bfc0…:311)
    at hotAddUpdateChunk (bootstrap ac9bfc0…:283)
    at webpackHotUpdateCallback (bootstrap ac9bfc0…:4)
    at 0.92fd6f4….hot-update.js:1

My Comments.js reads as follows:

import { subscriptionObservable } from '../apolloClient';

const Comments = React.createClass({
  
  constructor() {
    this.subscription = this.subscribe();
    console.log(`Subscribed for new messages with ID: ${this.subscription._networkSubscriptionId}`);
  },
  subscribe() {
    return subscriptionObservable.subscribe({
      error: (error) => {
        console.log(`Subscription error: ${error}`);
      },
      next: (result) => {
        console.log(`Subscription result: ${result}`);
      }
    });
  },
  render() {
    const comments = this.props.post.comments || [];
    return (
      <div className="comments">

        {_.map(comments, this.renderComment)}

        <form onSubmit={this.handleSubmit} ref="commentForm" className="comment-form">
          <input type="text" ref="author" placeholder="author"/>
          <input type="text" ref="comment" placeholder="comment"/>
          <input type="submit" hidden/>
        </form>
      </div>
    );
  }
});

Comments.propTypes = {
  client: React.PropTypes.instanceOf(ApolloClient).isRequired,
}
const CommentsWithApollo = withApollo(Comments);

export default CommentsWithApollo;

And my apolloClient.js reads as follows:

import ApolloClient, {
  createNetworkInterface,
  addTypeName,
} from 'apollo-client';

import { 
    SubscriptionClient, 
    addGraphQLSubscriptions,
} from 'subscriptions-transport-ws';

import { 
  Subscription_Add_Delete_Comment_Query,
} from './graphql/mutations-queries';

// Create WebSocket client
const wsClient = new SubscriptionClient('wss://subscriptions.graph.cool/v1/myID', {
  reconnect: true,
  connectionParams: {
    // Pass any arguments you want for initialization
  }
})
const networkInterface = createNetworkInterface({ 
  uri: 'https://api.graph.cool/simple/v1/myID',
  opts: {
    // Additional fetch options like `credentials` or `headers`
    credentials: 'same-origin',
  }
})

const networkInterfaceWithSubscriptions = addGraphQLSubscriptions(
  networkInterface,
  wsClient
)

const client = new ApolloClient({
  networkInterface: networkInterfaceWithSubscriptions,
  dataIdFromObject: (o) => o.id,
   addTypeName: true
})

let createDeleteSubscription = {
  query: Subscription_Add_Delete_Comment_Query,
  variables: {}
};

export let subscriptionObservable = client.subscribe(createDeleteSubscription);

export default client;

What am I overlooking here?

TheoG
  • 1,498
  • 4
  • 30
  • 54

1 Answers1

3

What you are overlooking here is the fact that you are mixing the es6 and es5 syntax of using react.

In the ES5 syntax this is how you create components -> const Comments = React.createClass Here you do not need to define a constructor. createClass does that for you.

In the ES6 syntax, this is how you create components -> class Comments extends React.Component And here you have to define your own constructor.

What you can do is either switch to the new syntax completely or do this.subscription = this.subscribe(); in a lifecycle method like componentWillMount or componentDidMount.

Jeff P Chacko
  • 4,908
  • 4
  • 24
  • 32