React-apollo: Apollo duplicates first result to every node in array of edges

Created on 16 Jan 2018  路  6Comments  路  Source: apollographql/react-apollo

Intended outcome:
I am trying to make a query to retrieve data for a React Native component. The query is resolved by a Django backend, with Graphene using a DjangoFilterConnectionField.

The query works fine on GraphiQL and it looks like this:
image

Actual outcome:
When the query is run by Apollo in the app, it duplicates the first result to every node in the array of edges. See the image below each node has id: "120" and name: "Acme Markets". It does recognize that it only received 4 results which is correct. There are no errors thrown in the console.
image

I found a workaround for this by using graphene.List instead DjangoFilterConnectionField. The problem is that graphene.List doesn't have built in pagination and filtering that Relay provides in DjangoFilterConnectionField.
image

To me this seems like an error with Apollo because the correct query results are showing up in graphiQL. Also I was using this format on a react app with DjangoFilterConnectionField on apollo-client 1.7.0 and react-apollo 1.4.2 with no problems a few months ago. So maybe the problem is due to v2 changes?

If you have any ideas on what to try or need further information to try and find the issue please let me know.

Version

Most helpful comment

Thanks :)
the above code in text format enjoy :)

cache: new InMemoryCache({
    dataIdFromObject: o => {o.id ? `${o.__typename}-${o.id}`: `${o.__typename}-${o.cursor}`},
  })

All 6 comments

Here is how to fix this problem:
screen shot 2018-01-17 at 10 40 19 am

You are a genius!! Thanks for saving me lot of trouble...

Thanks :)
the above code in text format enjoy :)

cache: new InMemoryCache({
    dataIdFromObject: o => {o.id ? `${o.__typename}-${o.id}`: `${o.__typename}-${o.cursor}`},
  })

@Vitiell0 @bhaumik-gandhi

do you mean to surround the function body with parenthesis such that dataIdFromObject is set to one of the options of the ternary operator? as it currently stands, you might as well directly set dataIdFromObject to undefined.

see a more thorough explanation at https://stackoverflow.com/questions/48840223/apollo-duplicates-first-result-to-every-node-in-array-of-edges/49249163#49249163

I resolved like this.

newEntry = newEntry.filter(edge => !previousEntry.some(PrevEdge => edge.node.id === PrevEdge.node.id))

Basically, you will need to remove duplicate from the new data set which comes in fetchMore function

Thanks :)
the above code in text format enjoy :)

cache: new InMemoryCache({
    dataIdFromObject: o => {o.id ? `${o.__typename}-${o.id}`: `${o.__typename}-${o.cursor}`},
  })

Should be

 dataIdFromObject: o => (o.id ? `${o.__typename}-${o.id}`: `${o.__typename}-${o.cursor}`),

However I improved/iterated some more upon this to below:

dataIdFromObject: (object) => {
        if (object.id) {
            // eslint-disable-next-line no-underscore-dangle
            return `${object.__typename}-${object.id}`;
        }
        if (object.cursor) {
            // Cursor edge instead, fixes invalid duplicate
            // eslint-disable-next-line no-underscore-dangle
            return `${object.__typename}-${object.cursor}`;
        }
        // Use a fallback to default handling if neither id nor cursor
        return defaultDataIdFromObject(object);
    },

But ended up not using it anyway because it caused me problems with fragments. Restored to manually filtering out the duplicate edges in our cache handler when updating query cache instead (before issusing the cache.writeQuery).

I'm rather new/novice on GraphQL so I might be doing things the wrong way around. If someone have the same problem with fragments becoming null and found a neater solution please do tell me.

Was this page helpful?
0 / 5 - 0 ratings