1
votes

I am trying to get prisma and relay working. Here's my repo:

https://github.com/jamesmbowler/prisma-relay-todo

It's a simple todo list. I am able to add the todos, but the ui does not update. When I refresh, the todo is there.

All of the examples of updating the store, that I can find, use a "parent" to the object that is being updated / created.

See https://facebook.github.io/relay/docs/en/mutations.html#using-updater-and-optimisticupdater

Also, the "updater configs" also requires a "parentID". https://facebook.github.io/relay/docs/en/mutations.html#updater-configs

From relay-runtime's RelayConnectionHandler.js comment here: https://github.com/facebook/relay/blob/master/packages/relay-runtime/handlers/connection/RelayConnectionHandler.js#L232

 * store => {
 *   const user = store.get('<id>');
 *   const friends = RelayConnectionHandler.getConnection(user, 'FriendsFragment_friends');
 *   const edge = store.create('<edge-id>', 'FriendsEdge');
 *   RelayConnectionHandler.insertEdgeAfter(friends, edge);
 * }

Is it possible to update the store without having a "parent"? I just have todos, with no parent.

Again, creating the record works, and gives this response:

{ "data" : { "createTodo" : { "id" : "cjpdbivhc00050903ud6bkl3x", "name" : "testing", "complete" : false } } }

Here's my updater function

updater: store => {
          const payload = store.getRootField('createTodo');

          const conn = ConnectionHandler.getConnection(store.get(payload.getDataID()), 'Todos_todoesConnection');

          ConnectionHandler.insertEdgeAfter(conn, payload, cursor);

},

I have done a console.log(conn), and it is undefined.

Please help.

----Edit---- Thanks to Denis, I think one problem is solved - that of the ConnectionHandler.

But, I still can't get the ui to update. Here's what I've tried in the updater function:

const payload = store.getRootField('createTodo');
const clientRoot = store.get('client:root');
const conn = ConnectionHandler.getConnection(clientRoot, 'Todos_todoesConnection');
ConnectionHandler.createEdge(store, conn, payload, 'TodoEdge');

I've also tried this:

const payload = store.getRootField('createTodo');
const clientRoot = store.get('client:root');
const conn = ConnectionHandler.getConnection(clientRoot, 'Todos_todoesConnection');
ConnectionHandler.insertEdgeAfter(conn, payload);

My data shape is different from their example, as I don't have the 'todoEdge', and 'node' inside my returned data (see above).

todoEdge { cursor node { complete id text } }

How do I getLinkedRecord, like this?

const newEdge = payload.getLinkedRecord('todoEdge');
1
Who is the parent? Is the query or is it any other type of your schema?Denis Cappelini
Here's the schema: github.com/jamesmbowler/prisma-relay-todo/blob/… - Yes, query is the parent, I believe.James Bowler

1 Answers

1
votes

If query is the parent, the parentID will be client:root.

Take a look at this: https://github.com/facebook/relay/blob/1d72862fa620a9db69d6219d5aa562054d9b93c7/packages/react-relay/classic/store/RelayStoreConstants.js#L18

Also at this issue: https://github.com/facebook/relay/issues/2157#issuecomment-385009482

create a const ROOT_ID = 'client:root'; and pass ROOT_ID as your parentID. Also, check the name of your connection on the updater, it has to be exactly equal to the name where you declared the query.

UPDATE: Actually, you can import ROOT_ID of relay-runtime

import { ROOT_ID } from 'relay-runtime';

UPDATE 2:

Your edit was not very clear for me, but I will provide you an example of it should work ok? After your mutation is run, you first access its data by using getRootField just like you are doing. So, if I have a mutation like:

  mutation UserAddMutation($input: UserAddInput!) {
    UserAdd(input: $input) {
      userEdge {
        node {
          name
          id
          age
        }
      }
      error
    }
  }

You will do:

const newEdge = store.getRootField('UserAdd').getLinkedRecord('userEdge');
      connectionUpdater({
        store,
        parentId: ROOT_ID,
        connectionName: 'UserAdd_users',
        edge: newEdge,
        before: true,
      });

This connectionUpdater is a helper function that looks likes this:

export function connectionUpdater({ store, parentId, connectionName, edge, before, filters }) {
  if (edge) {
    if (!parentId) {
      // eslint-disable-next-line
      console.log('maybe you forgot to pass a parentId: ');
      return;
    }

    const parentProxy = store.get(parentId);

    const connection = ConnectionHandler.getConnection(parentProxy, connectionName, filters);

    if (!connection) {
      // eslint-disable-next-line
      console.log('maybe this connection is not in relay store yet:', connectionName);
      return;
    }

    const newEndCursorOffset = connection.getValue('endCursorOffset');
    connection.setValue(newEndCursorOffset + 1, 'endCursorOffset');

    const newCount = connection.getValue('count');
    connection.setValue(newCount + 1, 'count');

    if (before) {
      ConnectionHandler.insertEdgeBefore(connection, edge);
    } else {
      ConnectionHandler.insertEdgeAfter(connection, edge);
    }
  }
}

Hope it helps :)