How do I use the React-Relay @appendNode directive with Hasura's generated functions/schema?
Asked Answered
R

1

6

I am currently trying to create an interface wherein a user is able to append additional metadata descriptors to an object while in a modal and need to reflect the results of this append elsewhere on the page. I am using react-relay with Hasura automatically creating a graphql schema/functions. I am currently trying to use the @appendNode directive to append the result of the following mutation to an existing edge with other present data so that it can be displayed to the user. The insert_dataset_metadata_one function returns just the metadata node that needs to be appended, so I put the directive between the function call and the fields to be returned from that node.

export const insertDatasetMetadata = graphql`
  mutation mutations_InsertDatasetMetadataMutation(
    $object: dataset_metadata_insert_input!
    $connectionIDs: [ID!]!
  ) {
    insert_dataset_metadata_one (
      object: $object
    ) @appendNode(connections: $connectionIDs, edgeTypeName: "dataset_metadataEdge") {
      id
      name: field_name
      value: field_value
      datasetMetadataId: dataset_metadata_id
      normalizedName: normalized_name
      normalizedValue: normalized_value
    }
  }
`;

On the TypeScript side, I call this mutation with the dataset object's relay ID (that is id; datasetId is the foreign key used in postgres to associate the inserted metadata with the object it's describing).

      const { id, datasetId, metadata } = dataset;
      // foreach over the metadata to get a data object and an if statement to test what needs updates and what needs inserts skipped for brevity
      commitMetadataInsert({
              variables: {
                object: {
                  dataset_id: datasetId ?? '',
                  field_name: data.name,
                  field_value: data.value,
                  normalized_name: data.normalizedName,
                  normalized_value: data.normalizedValue,
                },
                connectionIDs: [id],
              },
              onCompleted,
              onError,
            });

Strangely, this insert fails with the following error:

RRNLRequestError: Relay request for `mutations_InsertDatasetMetadataMutation` failed by the following reasons:

1. unexpected variables in variableValues: connectionIDs

Prior to adding the connectionIDs variable and the @appendNode directive, this mutation worked as expected, i.e. the inserted metadata was present on page reload; however, since I'm trying to avoid reloads, that isn't satisfactory. I've dug around and looked for resources inside/outside of the relay docs which could offer guidance on this directive but couldn't find anything to indicate what the cause could be or what to do in this scenario. I have confirmed that the id variable's value is what I expect it to be (i.e. the relay ID of the dataset.) What am I missing/doing incorrectly?

Rhebarhee answered 26/4, 2021 at 15:7 Comment(0)
A
1

I had the same issue.

The workaround is to remove the connectionIDs from the request variables, because this variable isn't used in the final graphql text, since the directive is client-side only, and not included in the final request (relay removes it before the fetch).

After removing the variable from the request, the directive worked perfectly on the client and created/appended the edge.

Example:

export const fetchGraphQL: FetchGraphQL = async (text, variables, url) => {

  // ...
  const { connectionsIDs, ...variablesWithoutConnections } = variables

  response = await fetch(url, {
    // ...
    body: JSON.stringify({
      query: text, // this text won't have client-side directives (e.g. @appendNode)
      variables: variablesWithoutConnections, // exclude client-side directive variables
    }),
  })

  // ...
}
Arcadian answered 29/1, 2023 at 20:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.