2

I am using the new version Keystone Next and I am trying to connect multiple items at once using an array of ids. It seems connect supports that, accepting an array of objects.

const FINISH_VOCABULARY_QUIZ_MUTATION = gql`
mutation FINISH_VOCABULARY_QUIZ_MUTATION(
    $userId: ID!
    $wordId: ID!
) {
    updateUser(id: $userId, data: {
        wrongAnswers: {
            connect: [{id: "idblabla"}, {id: "idblabla2"}]
        }
    }) {
        id
    }
}`;

But what I just can't seem to figure out is how do I pass this array of ids as a variable to my mutation. I understand that I would need to create a new type? The documentation is still unfinished, so there is nothing on that yet. I have also tried using string interpolation to form my query, but it seems that it's not a thing in GraphQl.

Dominik
  • 6,078
  • 8
  • 37
  • 61
Sava Vlad
  • 57
  • 1
  • 6
  • just pass `userId` and entire `data` object - `$data:someMutationInputType` read from API docs/specs – xadm Apr 20 '21 at 08:22

2 Answers2

3

This is more of a GraphQL question than a KeystoneJS but one but to head to the right direction here you'd need to change your query to something like below:

const FINISH_VOCABULARY_QUIZ_MUTATION = gql`
mutation FINISH_VOCABULARY_QUIZ_MUTATION(
    $userId: ID!,
    $ids: [UserWhereUniqueInput!]!
) {
    updateUser(id: $userId, data: {
        wrongAnswers: {
            connect: $ids
        }
    }) {
        id
    }
}`;

And then map your array of ids to an array of objects with id fields.

xadm
  • 8,219
  • 3
  • 14
  • 25
Dominik
  • 6,078
  • 8
  • 37
  • 61
  • Thanks for your answer! I eventually figured out that I can pass an array as a variable by just wrapping it in brackets like $wordsIdWrong: [WordWhereUniqueInput] – Sava Vlad Apr 30 '21 at 10:10
1

There is a better method:

const FINISH_VOCABULARY_QUIZ_MUTATION = gql`
mutation FINISH_VOCABULARY_QUIZ_MUTATION(
    $userId: ID!,
    $data: SomeAPIDefinedMutationUniqueInput
) {
    updateUser(id: $userId, data: $data)
      id
    }
}`;

This way you:

  • don't have to define types for internal arguments ($wordsIdWrong: [WordWhereUniqueInput]);
  • can reuse/share this mutation - import it from some, common for queries, place (dir) - just call it with different data variables;
  • easier for reading/maintenance;

PS. To be honest, there should be some specific [to quizes] mutation (don't use userUpdate for that), with user (or better quiz) id defined within SomeAPIDefinedUniqueInput.

xadm
  • 8,219
  • 3
  • 14
  • 25
  • Indeed that's something I could do, but that would mean defining a new type. As for the userUpdate, I need the data stored directly on the user and I don't want to make extra requests if not needed. – Sava Vlad Apr 30 '21 at 11:37
  • But it's good to know, i'll give it a try after I look more into GraphQL. – Sava Vlad Apr 30 '21 at 11:45
  • not a graphql problem - you can always use some `quizes` field under user type to connect other table/type (all graphql is about relations) ... it's more about DB design ... profile can be strictly under user but **limiting/taking care of amount of requests at type level is a premature optimization** ... quiz should be a separate type, attempts probably next (you can use the same quizes multiple times?) ... and using graphql you can use one request for all of them **for read** - it doesn't matter - all types should be managed (mutations) separately - nested mutations are problematic – xadm Apr 30 '21 at 12:09