Apollo-client: Gql arguments are required if defined in keyArgs

Created on 5 Sep 2020  ·  7Comments  ·  Source: apollographql/apollo-client

I'm unsure if this is intended behaviour and I can't seem to find much documentation on this feature as the documentation is being worked on (#6711).

I am using relayStylePagination / keyArgs like so

Intended outcome:

  • keyArgs should not require the argument to be defined in the gql query, if a key arg is defined in the InMemoryCache but not the specific gql, the key arg should be ignored
  • The error message (unless this is made redundant by above change) needs to be changed to an appropriate message for keyArgs

InMemoryCache

const cache = new InMemoryCache({
    Query: {
      fields: {
        contacts: relayStylePagination(["mine", "scopes", "propertyId"])
      },
    },
  },
});

gql

query GetContacts($mine: Boolean $cursor: String, $scopes: [ScopesEnum!]) { ... }

This causes issues if you have a large application with multiple gql files defined for the same field but with different arguments - my current work around is to write a function for the keyArgs and filter them depending on the arguments like so

const filterKeyArgsToArgs = (keyArgs: any) => (args: any) =>
  args ? keyArgs.filter((keyArg: any) => args.hasOwnProperty(keyArg)) : null;

const cache = new InMemoryCache({
    Query: {
      fields: {
        contacts: relayStylePagination(filterKeyArgsToArgs(["mine", "scopes", "propertyId"]))
      },
    },
  },
});

Actual outcome:

I get the following error (which is worded for key fields) when the propertyId key arg is defined in the InMemoryCache but not in the gql

Invariant Violation: Missing field 'propertyId' while computing key fields

How to reproduce the issue:

  • Define keyargs for a field in the InMemoryCache
  • Have a gql query for that field which uses those arguments - works fine
  • Have a gql query for that field which does not use those arguments - does not work (gets above error)

Let me know if you need to create a demo

Versions

  System:
    OS: Linux 5.4 Ubuntu 18.04.5 LTS (Bionic Beaver)
  Binaries:
    Node: 12.18.3 - /usr/bin/node
    Yarn: 1.22.5 - /usr/bin/yarn
    npm: 6.14.7 - /usr/bin/npm
  Browsers:
    Chrome: 85.0.4183.83
    Firefox: 80.0.1
  npmPackages:
    @apollo/client: ^3.1.4 => 3.1.4
idea 🍪 feature-request 🛫 in-progress 🧞‍♂️ enhancement

Most helpful comment

@zsaraf I believe relayStylePagination and all the other pagination helpers are more guides on how to guide your pagination helper?

Either way they should still be usable (and the fact that this affects all keyArgs! not just relayStylePagination).

Here is my solution:

const filterKeyArgsToArgs = (keyArgs: any) => (args: any) =>
  args ? keyArgs.filter((keyArg: any) => args.hasOwnProperty(keyArg)) : null;

const cache = new InMemoryCache({
    Query: {
      fields: {
        contacts: relayStylePagination(filterKeyArgsToArgs(["mine", "scopes", "propertyId"]))
      },
    },
  },
});

Basically you can pass a function into relayStylePagination / keyArgs which will receive the current arguments, then filter out the keyargs which aren't in the arguments. Let me know if you have any trouble with it, it's what i've been using in production for the past couple weeks after removing updateQuery.

All 7 comments

Having this exact same issue, let me know if you've come up with a solution! Doesnt seem like relayStylePagination is ready for production, so I'm curious as to why updateQuery was deprecated.

@zsaraf I believe relayStylePagination and all the other pagination helpers are more guides on how to guide your pagination helper?

Either way they should still be usable (and the fact that this affects all keyArgs! not just relayStylePagination).

Here is my solution:

const filterKeyArgsToArgs = (keyArgs: any) => (args: any) =>
  args ? keyArgs.filter((keyArg: any) => args.hasOwnProperty(keyArg)) : null;

const cache = new InMemoryCache({
    Query: {
      fields: {
        contacts: relayStylePagination(filterKeyArgsToArgs(["mine", "scopes", "propertyId"]))
      },
    },
  },
});

Basically you can pass a function into relayStylePagination / keyArgs which will receive the current arguments, then filter out the keyargs which aren't in the arguments. Let me know if you have any trouble with it, it's what i've been using in production for the past couple weeks after removing updateQuery.

Thank you @tadhglewis!

@tadhglewis I think allowing optional arguments in keyArgs is the right solution here! Fix incoming: #7109

It looks like it is currently working. Maybe I did use keyFields instead of
keyArgs ...

Apologies...

Op ma 7 dec. 2020 om 19:15 schreef Ben Newman notifications@github.com:

@robertsmit https://github.com/robertsmit #7109 (comment)
https://github.com/apollographql/apollo-client/pull/7109#issuecomment-740089023


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/apollographql/apollo-client/issues/6973#issuecomment-740089704,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/ABY2H3667PPBTCZ5GVAILFDSTULSZANCNFSM4QZZCHQQ
.

Can't test whether this is or isn't working as I'm no longer working on the project I was using this on.

I'm assuming this is fine to close this issue now. @benjamn ?

Was this page helpful?
0 / 5 - 0 ratings