Apollo duplicates first result to every node in array of edges

apollo-cache-inmemory
apollo updatequery
apollo-angular update
apollo query update
apollo client addtypename
apollo cache not updating
apollo client resetstore
apollo cache not working

I am working on a react app with react-apollo calling data through graphql when I check in browser network tab response it shows all elements of the array different but what I get or console.log() in my app then all elements of array same as the first element. I don't know how to fix please help

Put this in your App.js

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

Apollo duplicates first result to every node in array of edges, Put this in your App.js cache: new InMemoryCache({ dataIdFromObject: o => o.id ? `${o.__typename}-${o.id}` : `${o.__typename}-${o.cursor}`,� 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.

The reason this happens is because the items in your array get "normalized" to the same values in the Apollo cache. AKA, they look the same to Apollo. This usually happens because they share the same Symbol(id).

If you print out your Apollo response object, you'll notice that each of the objects have Symbol(id) which is used by Apollo cache. Your array items probably have the same Symbol(id) which causes them to repeat. Why does this happen?

By default, Apollo cache runs this function for normalization.

export function defaultDataIdFromObject(result: any): string | null {
  if (result.__typename) {
    if (result.id !== undefined) {
      return `${result.__typename}:${result.id}`;
    }
    if (result._id !== undefined) {
      return `${result.__typename}:${result._id}`;
    }
  }
  return null;
}

Your array item properties cause multiple items to return the same data id. In my case, multiple items had _id = null which caused all of these items to be repeated. When this function returns null the docs say

InMemoryCache will fall back to the path to the object in the query, such as ROOT_QUERY.allPeople.0 for the first record returned on the allPeople root query.

This is the behavior we actually want when our array items don't work well with defaultDataIdFromObject.

Therefore the solution is to manually configure these unique identifiers with the dataIdFromObject option passed to the InMemoryCache constructor within your ApolloClient. The following worked for me as all my objects use _id and had __typename.

const client = new ApolloClient({
  link: authLink.concat(httpLink),
  cache: new InMemoryCache({
    dataIdFromObject: o => (o._id ? `${o.__typename}:${o._id}`: null),
  })
});

First Impressions with Apollo Client 3 - Apollo Blog, With the upcoming release of Apollo Client 3, I thought it would be an excellent time to test out the latest beta In 3.0 all cache results are now frozen/immutable, and it introduces a new declarative API for Suppose you want to merge arrays or non-normalized objects. cards).filter( edge => edge.node. 11 Apollo duplicates first result to every node in array of edges Mar 13 '18 8 react-bootstrap contains no css Mar 15 '16 6 How to check for custom OpenID claim in an IAM role's trust policy?

I believe the approach in other two answers should be avoided in favor of following approach:

Actually it is quite simple. To understand how it works simply log obj as follows:

dataIdFromObject: (obj) => {
let id = defaultDataIdFromObject(obj);
console.log('defaultDataIdFromObject OBJ ID', obj, id);

You will see that id will be null in your logs if you have this problem.

Pay attention to logged 'obj'. It will be printed for every object returned.

These objects are the ones from which Apollo tries to get unique id ( you have to tell to Apollo which field in your object is unique for each object in your array of 'items' returned from GraphQL - the same way you pass unique value for 'key' in React when you use 'map' or other iterations when rendering DOM elements).

From Apollo dox:

By default, InMemoryCache will attempt to use the commonly found primary keys of id and _id for the unique identifier if they exist along with __typename on an object.

So look at logged 'obj' used by 'defaultDataIdFromObject ' - if you don't see 'id' or '_id' then you should provide the field in your object that is unique for each object.

I changed example from Apollo dox to cover three cases when you may have provided incorrect identifiers - it is for cases when you have more than one GraphQL types:

dataIdFromObject: (obj) => {
let id = defaultDataIdFromObject(obj);
console.log('defaultDataIdFromObject OBJ ID', obj, id);

if (!id) {
const { __typename: typename } = obj;
switch (typename) {

case 'Blog':
// if you are using other than 'id' and '_id' - 'blogId' in this case
const undef = `${typename}:${obj.id}`;
const defined = `${typename}:${obj.blogId}`;
console.log('in Blogs -', undef, defined);
return `${typename}:${obj.blogId}`; // return 'blogId' as it is a unique
//identifier. Using any other identifier will lead to above defined problem.

case 'Post':
// if you are using hash key and sort key then hash key is not unique.
// If you do query in DB it will always be the same.
// If you do scan in DB quite often it will be the same value. 
// So use both hash key and sort key instead to avoid the problem.
// Using both ensures ID used by Apollo is always unique.
// If for post you are using hashKey of blogID and sortKey of postId
const notUniq = `${typename}:${obj.blogId}`;
const notUniq2 = `${typename}:${obj.postId}`;
const uniq = `${typename}:${obj.blogId}${obj.postId}`;
console.log('in Post -',  notUniq, notUniq2, uniq);
return `${typename}:${obj.blogId}${obj.postId}`;

case 'Comment':
// lets assume 'comment's identifier is 'id'
// but you dont use it in your app and do not fetch from GraphQl, that is
// you omitted 'id' in your GraphQL query definition.
const undefnd = `${typename}:${obj.id}`;
console.log('in Comment -', undefnd);  
// log result - null
// to fix it simply add 'id' in your GraphQL definition.
return `${typename}:${obj.id}`;

default:
console.log('one falling to default-not good-define this in separate Case', ${typename});
return id;

I hope now you see that the approach in other two answers are risky.

YOU ALWAYS HAVE UNIQUE IDENTIFIER. SIMPLY HELP APOLLO BY LETTING KNOW WHICH FIELD IN OBJECT IT IS. If it is not fetched by adding in query definition add it.

Optimizing Your GraphQL Request Waterfalls, The most obvious one is to think in terms of Nodes, Edges and Connections: have an edge to each account, and their labels would indicate whether the Surely this would result in far fewer requests? Become an Apollo insider and get first access to new features, best practices, and community events. @kedarguy thanks for the response, but actually it gets stuck at the first line – it throws an error: Error: Cannot find module 'apollo-fetch' I'm using the nuxt apollo module (this repo), so my nuxt.config.js is the following (more or less, just the corresponding parts):

apollo, Apollo duplicates first result to every node in array of edges. I am working on a react app with react-apollo calling data through graphql when I check in browser � The input graph consists of two arrays, one that contains all edges sorted by the start node, and one array of size | V | that stores, for each vertex, its out-degree and offset into the first array. 8.5.1 *External Priority Queues. External priority queues for general weights are involved.

Pagination, hero { name friends(first:2) { edges { node { name } cursor } } } } of the additional information that the edge contains, we don't need to query for the edges at all,� Output: Linked list with no duplicates. Approach: Create a Hash Map; Take two pointers, prevNode and CurrNode. PrevNode will point to the head of the linked list and currNode will point to the head.next. Now navigate through the linked list. Check every node data is present in the Hash Map. if yes then delete that node using prevNode and currNode.

Queries and Mutations, Let's start by looking at a very simple query and the result we get when we run it: Note that in this example, the friends field returns an array of items. But in GraphQL, every field and nested object can get its own set of arguments, making GraphQL a name friendsConnection(first: $first) { totalCount edges { node { name } Apollo Server is built with the following principles in mind: By the community, for the community : Apollo Server's development is driven by the needs of developers using the library. Simplicity : Keeping things simple, for example supporting a limited set of transports, makes Apollo Server easier to use, easier to contribute to, and more secure.

Comments
  • 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
  • @Simon Good point, I've edited the original answer to reflect your suggestion
  • Hi, I tried your solution but seems that property 'cursor' does not exist on type 'IdGetterObj' . Have you some other suggestion to work with object that couldn't have as fields 'id' or '_id' ?
  • More succinctly, ensure that you are not returning a duplicate ID object in graphql. In my case this was the result of our ID being left NULL.
  • Helpful. Thanks! 👍