Howtographql: (React + Apollo) Realtime Updates with Subscriptions gives error

Created on 9 Apr 2018  路  5Comments  路  Source: howtographql/howtographql

Got this nasty error when trying to subscribe to new links:

Store error: the application attempted to write an object with no provided typename but the store already contains an object with typename of Feed for the object of id $ROOT_QUERY.feed. The selectionSet that was trying to be written is:
feed {
  links {
    id
    createdAt
    url
    description
    postedBy {
      id
      name
      __typename
    }
    votes {
      id
      user {
        id
        __typename
      }
      __typename
    }
    __typename
  }
  __typename
}

It goes away if I change the updateQuery to look like this (note the explicit __typename):

updateQuery: (previous, { subscriptionData }) => {
    const newAllLinks = [
        subscriptionData.data.newLink.node,
        ...previous.feed.links
    ]
    const result = {
        ...previous,
        feed: {
            links: newAllLinks,
            __typename: 'Feed'
        }
    }
    return result
}

I'm curious if there's a reason it needs that __typename now, or if maybe I've goofed somewhere along the way.

BTW, the only way I deviated from this tutorial was by using my own hackernews-node repo rather than cloning the one provided. That could possibly be related?

Most helpful comment

Yeah, I came across that suggestion to check that all id's are being queried, but they certainly are. And I also had noticed that subscriptions work just fine in the playground. So it's definitely something going on with the Apollo functions, in particular I think the updateQuery callback. Based on the error message (and inspecting the variables in the Chrome debugger) I saw that the only difference between the previous object and the object we are returning is that it's missing the __typename on feed.

Rather than explicitly having to set the __typename variable, it might be better to just spread the properties of the nested object like this:

updateQuery: (previous, { subscriptionData }) => {
    const newAllLinks = [
        subscriptionData.data.newLink.node,
        ...previous.feed.links
    ]
    const result = {
        ...previous,
        feed: {
            ...previous.feed,
            links: newAllLinks
        }
    }
    return result
}

That's not entirely unexpected, and it's a pattern that's shown up in Redux reducers a lot (when not using an immutable library).

All 5 comments

Hi Josh,
I am using the server provided and am still getting the same error as you.
According to this forum post

The error message always indicates that somewhere in a query, in a mutation query, or in a subscription query, you forgot to query the id of a node.

I can't figure out why it is happening. When I run the subscription query in the playground it returns the expected results when new links are added:

{
  "data": {
    "data": {
      "newLink": {
        "node": {
          "id": "cjfsx3e41kbzp0b62xu1djb1j",
          "url": "www.theURL.com",
          "description": "the description of url",
          "createdAt": "2018-04-10T00:18:11.000Z",
          "postedBy": null,
          "votes": []
        }
      }
    }
  }
}

Note, this error does not occur for the 'Subscribing to new votes' section of the tutorial.

Yeah, I came across that suggestion to check that all id's are being queried, but they certainly are. And I also had noticed that subscriptions work just fine in the playground. So it's definitely something going on with the Apollo functions, in particular I think the updateQuery callback. Based on the error message (and inspecting the variables in the Chrome debugger) I saw that the only difference between the previous object and the object we are returning is that it's missing the __typename on feed.

Rather than explicitly having to set the __typename variable, it might be better to just spread the properties of the nested object like this:

updateQuery: (previous, { subscriptionData }) => {
    const newAllLinks = [
        subscriptionData.data.newLink.node,
        ...previous.feed.links
    ]
    const result = {
        ...previous,
        feed: {
            ...previous.feed,
            links: newAllLinks
        }
    }
    return result
}

That's not entirely unexpected, and it's a pattern that's shown up in Redux reducers a lot (when not using an immutable library).

I too was seeing this error and thought I was crazy or missed an update somewhere in the tutorial. Adding your fix of spreading the previous.feed into the result feed worked, as we now have a __typename on feed and no more errors - thanks @josh-stevens!

I wonder what's changed since the tutorial was written, as I'm assuming it must have worked before.

Thank you @josh-stevens , I was going crazy as well and your information helped me solved that problem 馃憤

Thanks @josh-stevens for opening this issue 馃槃It should be fixed. Closing this!

Was this page helpful?
0 / 5 - 0 ratings