在突变中继后现代连接处理程序是未定义的

时间:2017-09-20 20:37:45

标签: graphql relayjs relay relaymodern

我正在做多个项目的变异。但updater中的连接处理程序返回undefined。我正在处理shopItems类型,这是相关的架构

type Mutation {
  shopItem(input: itemsInput): addedItems
}

type addedItems {
  addedItems: [itemEdge]
}

type itemEdge {
  cursor: Int
  node: itemNode
}

type itemNode implements Node {
  id: ID!,
  name: String,
  price: Int
}

type Root {
  viewer: viewer
}

type viewer {
  id: ID!
  shopItems(ShopId: ID, SubCategoryId:ID, first:Int, last: Int): Item
}

type Item {
  pageInfo: PageInfo
  edges: [itemEdge]
}

这是shopItems查询的片段,

module.exports = createFragmentContainer(
  Item,
  graphql`
    fragment item_viewer on viewer {
      // the global parent viewer id
      id,
      shopItems(first:$first,last:$last,ShopId:$ShopId,SubCategoryId:$SubCategoryId) @connection(key: "item_shopItems",filters:["first","last"]){

     // didn't want the pageInfo here yet but relay compiler enforces this because of @connection. It's basically returning null.
        pageInfo {
          hasNextPage
          endCursor
        }
        edges {
          cursor // returns null as well
          node {
            id
            name
            price
          }
        }
      }
    }
  `
)

添加shopItems的变异返回addedItems数组,

mutation addShopItemMutation($input: itemsInput) {
    shopItem(input: $input) {
      addedItems {
        node {
          id
          name
          price
        }
      }
    }
  }


commitMutation(
        environment,
        {
        ...
        updater: (store) => {
          const payload = store.getRootField('shopItem');

          //I've seen everyone using getLinkedRecord, but in my case the mutation return type is an array and it gives an error so I'm using getLinkedRecords. I think this is where the problem lies.

          const newItem = payload.getLinkedRecords('addedItems');
          this.sharedUpdate(store, this.props.viewerId, newItem)
        }
      })

sharedUpdate(store, viewerId, newItem) {

    //viewerProxy here is not undefined
    const viewerProxy = store.get(viewerId);

    //conn is undefined
    const conn = ConnectionHandler.getConnection(
    viewerProxy,
    'item_shopItems',
    );
    if(conn)  {
      ConnectionHandler.insertEdgeAfter(conn, newItem);
    }
  }

由于某种原因,连接返回undefined。另外当我在console.log viewerProxy时,我确实看到了连接键" item_shopItems"但是新的边缘并没有出现在那里。以防万一,我在服务器端使用Node Js - Express。

另一个问题是addedItem不是单数,而是数组。

1 个答案:

答案 0 :(得分:0)

你需要为shopItems查询使用分页:

module.exports = createPaginationContainer(
  ShopItems,
  {
    viewer: graphql`
      fragment ShopItems_viewer on Viewer {
        id
        shopItems(
          first: $count
          after: $cursor
          ShopId: $ShopId
          SubCategoryId: $SubCategoryId
        )
          @connection(
            key: "ShopItems_shopItems"
            filters: ["ShopId", "SubCategoryId"]
          ) {
          edges {
            cursor
            node {
              id
              name
              price
            }
          }
        }
      }
    `
  },
  {
    direction: 'forward',
    getConnectionFromProps(props) {
      return props.viewer.shopItems;
    },
    getFragmentVariables(prevVars, totalCount) {
      return {
        ...prevVars,
        count: totalCount
      };
    },
    getVariables(props, { count, cursor }, fragmentVariables) {
      return {
        count,
        cursor,
        ShopId: fragmentVariables.ShopId,
        SubCategoryId: fragmentVariables.SubCategoryId
      };
    },
    query: graphql`
      query ShopItemsQuery(
        $count: Int!
        $cursor: String
        $ShopId: ID
        $orderBy: ID
      ) {
        viewer {
          ...ShopItems_viewer
        }
      }
    `
  }
);

注意:filters: []中没有@connectionafterfirstbefore

last

突变:

/**
 * @flow
 */
import { commitMutation, graphql } from 'react-relay';
import { ConnectionHandler } from 'relay-runtime';
import environment from '../utils/createRelayEnvironment';

type Options = {
  onSuccess: Function,
  onFailure: Function
};

const defaultCallbacks: Options = { onSuccess: () => {}, onFailure: () => {} };

const mutation = graphql`
  mutation AddShopItemMutation($input: itemsInput) {
    shopItem(input: $input) {
      addedItems {
        cursor
        node {
          id
          name
          price
        }
      }
    }
  }
`;

function sharedUpdater(store, viewer, addedItemsEdge, nameConnection, filters) {
  const viewerProxy = store.get(viewer.id);

  const connection = ConnectionHandler.getConnection(
    viewerProxy,
    nameConnection,
    filters // your connection undefined is do missing filters
  );

  if (connection) {
    ConnectionHandler.insertEdgeBefore(connection, addedItemsEdge);
  }
}

let nextClientMutationId = 0;

function commit(
  viewer: Object,
  input: Object,
  nameConnection: string,
  filters: Object, // { ShopId: ID, SubCategoryId: ID };
  // const { ShopId, SubCategoryId } = this.context.relay.variables
  cb: Options = defaultCallbacks
): any {
  nextClientMutationId += 1;

  return commitMutation(environment, {
    mutation,
    variables: {
      input: {
        ...input,
        clientMutationId: nextClientMutationId
      }
    },
    onCompleted: cb.onSuccess,
    onError: cb.onFailure,
    updater(store) {
      const payload = store.getRootField('addShopItem');

      sharedUpdater(
        store,
        viewer,
        payload.getLinkedRecords('addedItems'),
        nameConnection,
        filters
      );
    }
  });
}

export default { commit };