readField not working on nested data

Using GitHub’s GraphQL API, I’m trying to figure out the “right” way to sort my respositories by the number of open PRs:

Here’s my query:

  query GetRepositories($after: String) {
    search(
      type: REPOSITORY
      query: "org:TryGhost archived:false fork:false"
      first: ${DEFAULT_REPOS}
      after: $after
    ) {
      repositoryCount
      pageInfo {
        endCursor
        hasNextPage
      }
      nodes {
        ...RepositoryTile
      }
    }
  }
  ${REPOSITORY_TILE_DATA}

My fragment REPOSITORY_TILE_DATA

 fragment RepositoryTile on Repository {
    id
    nameWithOwner
    name
    url
    pullRequests(states: OPEN, first: 100) {
      totalCount
      nodes {
        isRenovate @client
        author {
          login
        }
        url
      }
    }
  }

And then finally my typePolicies

typePolicies: {
        Query: {
            fields: {
                search: {
                    keyArgs: [],
                    merge(existing = {}, incoming) {
                        const existingNodes = existing.nodes || [];
                        const incomingNodes = incoming.nodes || [];

                        return {
                            ...existing,
                            ...incoming,
                            nodes: [...existingNodes, ...incomingNodes],
                            pageInfo: incoming.pageInfo
                        };
                    },
                    read(existing, {readField, toReference}) {
                        if (!existing || !existing.nodes) {
                            return existing;
                        }

                        if (existing.nodes.length > 0) {
                            const sortedNodes = [...existing.nodes].sort((a, b) => {
                                console.log(readField('name', a));
                                console.log(readField('pullRequests', a));

                                // return b.pullRequests.totalCount - a.pullRequests.totalCount;
                                return 0;
                            });

                            return {
                                ...existing,
                                nodes: sortedNodes
                            };
                        }

                        return existing;
                    }
                }
            }
        },
        Repository: {
            keyFields: ['nameWithOwner']
        },
        PullRequest: {
            keyFields: ['number'],
            fields: {
                isRenovate: {
                    read(_, {readField}) {
                        return readField('author').login === 'renovate' ? true : false;
                    }
                }
            }
        }
    }

You can see the sort I’m trying to do on pullRequests.totalCount

This works as expected: console.log(readField('name', a));
But this is undefined: console.log(readField('pullRequests', a));

isReference('pullRequests', a) returns false

I’m struggling to understand what pullRequests are in this case, or how to access them…

Banging my head against this still.

Why does readField('author').login work on pull requests - that’s nested…

But this doesn’t work on a repository:

readField('pullRequests', a)

Here’s what I see in the cache:

image

I’ve tried:

readField('pullRequests', a)
readField('pullRequests.nodes', a)
readField('pullRequests.totalCount', a)
readField('PullRequests', a)
readField('PullRequest', a)
readField('PullRequestConnection', a)
readField('pullRequests({"first":100,"states":"OPEN"})', a)

And changing the query to

prs:pullRequests({"first":100,"states":"OPEN"})' and then doing readField('prs', a)

Every time it’s undefined.

:grimacing:

Someone please put me out of my misery - what am I missing?

Not 100% sure if this will fix the problem but try this maybe:
readField({ from: a, fieldName: 'pullRequests', args: { first: 100, states: 'OPEN' } })

OMG THIS TOTALLY WORKED THANK YOU :heart:

I cannot tell you how much this has been hurting me - I was so sure there had to be a way. Where did you find this / how did you figure it out? Is there some magical missing reference to readField somewhere?

1 Like

Found it by digging through the typescript types. If you’re using VSCode you can press F12 when the cursor is on the readField function and it will bring you to the typescript definition. Or it can also be seen here: https://github.com/apollographql/apollo-client/blob/630ec1f4b65d0c83986d47acf7bba7f906082304/src/cache/core/types/common.ts#L34-L52