1

I'm working on standing up a simple Relay/GraphQL app using Node.

At the root level, I have a connection called 'notes' that paginates all notes in the database. On my user object, I have a notes connection that paginates all notes that user has created.

  const rootNotesId = ConnectionHandler.getConnectionID('client:root', 'RootNotesConnection_notes');
  const userNotesId = ConnectionHandler.getConnectionID(queryData?.me?.id, 'UserNotesConnection_notes');
  
  const rootNotes = usePaginationFragment(graphql `
    fragment NotesRoot_notes on Query @refetchable(queryName: "NotesRootQuery") {
      notes(first: $count, after: $cursor) @connection(key: "RootNotesConnection_notes") {
        edges {
          node {
            ...Note_note
          }
        }
      }
    }
  `, queryData);
  
  const userNotes = usePaginationFragment(graphql`
    fragment NotesUser_notes on Query @refetchable(queryName: "NotesUserQuery") {
      me {
        id
        notes(first: $count, after: $cursor) @connection(key: "UserNotesConnection_notes") {
          edges {
            node {
              ...Note_note
            }
          }
        }
      }
    }
  `, queryData);

How do I add or delete a note to both connections at once client-side? I have two different edge types and I thought this code would work:

  const [commit, isInFlight] = useMutation(graphql `
    mutation NotesCreateMutation($input: createNoteInput!) {
      createNote(input: $input) {
        noteEdge {
          cursor,
          node {
            id
            user {
              username
            }
            content
          }
        }
      }
    }
  `);
  
  const handleButtonClick = () => {
    if (!isInFlight) {
      commit({
        variables: {
          input: {
            content: newNoteInput
          }
        },
        updater: store => {
          const rootCon = ConnectionHandler.getConnection(store.get('client:root'), 'RootNotesConnection_notes');
          const userCon = ConnectionHandler.getConnection(store.get(userId), 'UserNotesConnection_notes');
          const payload = store.getRootField('createNote');
          const newEdge = payload.getLinkedRecord('noteEdge');
          const newNote = newEdge.getLinkedRecord('node');
          debugger;
          const newRootEdge = ConnectionHandler.createEdge(store, rootCon, newNote, 'QueryNotesEdge');
          const newUserEdge = ConnectionHandler.createEdge(store, userCon, newNote, 'UserNotesEdge');
          ConnectionHandler.insertEdgeAfter(rootCon, newRootEdge);
          ConnectionHandler.insertEdgeAfter(userCon, newUserEdge);
        }
      });
      setNewNoteInput('');
    }
  }

The only thing I can find in my debugging is that the cursor never gets set for the new edge. Stepping through this code in the debugger reveals that all variables before newRootEdge resolve just fine

1 Answers1

0

This worked. Thanks to this thread for a good workaround: https://github.com/facebook/relay/issues/2761

const handleButtonClick = () => {
    if (!isInFlight) {
      commit({
        variables: {
          input: {
            content: newNoteInput
          }
        },
        updater: store => {
          const rootCon = ConnectionHandler.getConnection(store.get('client:root'), 'RootNotesConnection_notes');
          const payload = store.getRootField('createNote');
          const newRootEdge = payload.getLinkedRecord('noteEdge');
          const prevRootEdges = rootCon.getLinkedRecords('edges');
          const nextRootEdges = [...prevRootEdges, newRootEdge];
          rootCon.setLinkedRecords(nextRootEdges, 'edges');
          
          const userCon = ConnectionHandler.getConnection(store.get(userId), 'UserNotesConnection_notes');
          const newNote = newRootEdge.getLinkedRecord('node');
          const newUserEdge = ConnectionHandler.createEdge(store, userCon, newNote, 'UserNotesEdge');
          newUserEdge.setValue(newRootEdge.getValue('cursor'), 'cursor');
          const prevUserEdges = userCon.getLinkedRecords('edges');
          const nextUserEdges = [...prevUserEdges, newUserEdge];
          userCon.setLinkedRecords(nextUserEdges, 'edges');
        }
      });
      setNewNoteInput('');
    }
  }