Apollo-client: Issue with subscriptions: this.subscription.unsubscribe is not a function

Created on 7 Jan 2017  路  2Comments  路  Source: apollographql/apollo-client

Hi,

Hopefully this is an appropriate place to get some help, I am having some trouble with subscriptions and unsubscribing when a particular prop changes. Basically I have this component Channel which has the following:

    componentWillReceiveProps(newProps){
        if (!newProps.loading) {
            if (this.subscription) {
                if (newProps.channelId !== this.props.channelId) {
                    this.subscription.unsubscribe();
                } else {                    
                    return;
                }
            }
            this.subscription = newProps.subscribeToMore({
                document: subscribeForAddedMessages,
                variables: { channelId: newProps.channelId },

                updateQuery: (previousResult, { subscriptionData }) => {
                    let newResult = Object.assign({}, previousResult)
                    newResult.messages = [...previousResult.messages, subscriptionData.data.messageAdded]
                    return newResult                     
                },
                onError: (err) => console.error(err),
            });
        }
    }

This is the container:

export default compose(
    graphql(MessagesForChannelQuery, {
        options: (ownProps) => ({
            variables: {
                channelId: ownProps.channelId,
                orderBy: 'createdOn',
            },
        }),
        props: ({ ownProps, data: { loading, messages, error, subscribeToMore, variables } }) => ({
            loading,
            messages,
            error,
            subscribeToMore,
            variables
        }),
    }),
)(ChannelView);

And this is me using such wrapped component:
<Channel channelId={params.channelId} />

Basically when params.channelId changes and i need to unsubscribe and resubscribe to the new channel, however I am getting this.subscription.unsubscribe is not a function being thrown when switching channels.

As far as I can tell I am not doing anything outside of the ordinary. Does anyone know why this.subscription would exist but not this.subscription.unsubscribe()?

"apollo-client": "^0.5.26",

Most helpful comment

@deep-c It's not defined because you're not actually getting an observable back. Apollo Client subscribes to it for you, so all you get back is actually the unsubscribe handle. So if you call this.subscription() it will unsubscribe. Maybe the variable name I chose in GitHunt-React isn't great 馃槃 . Would be better to call it unsubscribeHandle or something.

All 2 comments

@deep-c It's not defined because you're not actually getting an observable back. Apollo Client subscribes to it for you, so all you get back is actually the unsubscribe handle. So if you call this.subscription() it will unsubscribe. Maybe the variable name I chose in GitHunt-React isn't great 馃槃 . Would be better to call it unsubscribeHandle or something.

@helfer looks like auto-unsubscribe is not working, and that I do in fact need to unsubscribe in the "componentWillUnmount" lifecycle method, because i keep getting the following error:

Can only update a mounted or mounting component. This usually means you called setState, replaceState, or forceUpdate on an unmounted component. This is a no-op.
Please check the code for the Messages component.

  • screens/Chat/Messages.js:126:26 in updateQuery

The setState that's being called, is inside my subscribeToMore updateQuery method, in a component that has been unmounted.

So how do I manually unsubscribe in "componentWillUnmount"? Calling this.props.data.subscribeToMore() to unsubscribe, as suggested elsewhere, breaks my code with the following error: undefined is not an object (evaluating 'options.document'), and there doesn't exist an unsubscriber method on this.props.data , and neither does one exist in this.props.data.subscribeToMore({...})

Please note that this is Apollo v1... v2 is not an option for this app.

Please help, thank you!

Was this page helpful?
0 / 5 - 0 ratings