I'm doing a mutation of multiple items. But the connection handler in updater returns undefined. I'm dealing with the shopItems type, Here's the relevant schema
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]
}
this is the fragment for shopItems query,
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
}
}
}
}
`
)
the mutation for adding shopItems returns array of 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);
}
}
For some reason the connection returns undefined. Also when I console.log viewerProxy, I do see the connection key "item_shopItems" but the new edge doesn't appear there. Just in case, I'm using Node Js - Express on server side.
Another problem is that the addedItem is not singular, but an array.
you need using pagination for shopItems query:
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
}
}
`
}
);
note: filters: []
in @connection
without after
, first
, before
and last
the mutation:
/**
* @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 };
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.