Relay: Cannot Update Relay Store with RANGE_DELETE

Created on 24 Jul 2017  路  12Comments  路  Source: facebook/relay

Hi All I'm struggling in updating a list of object when delete a range:

this is my query to fetch the leads

query LeadsQuery (
      $cursor: String
      $count: Int!
      $orderBy: String
      $direction: String
    ){
      me { ...Layout_me }
      ...Leads_data @arguments(count: $count, cursor: $cursor, direction: $direction, orderBy: $orderBy)
    }
  `

this is my refetchContainer in my component to fetch the leads

export default createRefetchContainer(
  Leads,
  {
    data: graphql.experimental`fragment Leads_data on Query 
      @argumentDefinitions(
        count: { type: "Int", defaultValue: 10 }
        cursor: { type: "String" }
        orderBy: { type: "String" }
        direction: { type: "String" }
      ) @connection(key: "Leads_data") {
      leads (
        first: $count
        after: $cursor
        orderBy: $orderBy
        direction: $direction
      ) @connection(key: "Leads_leads") {
        totalCount
        orderBy
        direction
        pageInfo {
          hasNextPage
          hasPreviousPage
          startCursor
          endCursor
        }
        edges {
          cursor
          node {
            id
            createdAt
            sellHorizon
            user {
              firstName
              lastName
            }
          }
        }
      }
    }`,
  },
  graphql.experimental`
    query LeadsRefetchQuery (
      $cursor: String
      $count: Int!
      $orderBy: String
      $direction: String
    ){
      ...Leads_data @arguments(count: $count, cursor: $cursor, direction: $direction, orderBy: $orderBy)
    }
  `,
)

This is my mutation

``` commitMutation(relayModernEnvironment, { mutation: graphql
mutation LeadsDeleteMutation($input: DeleteLeadsInput!){
deleteLeads(input: $input) {
deletedLeadId
}
}
`,
variables: {
input: {
id: ids,
},
},
onError: (errors) => {
console.log(errors);
},
onCompleted: (response) => {
console.log(response);
},
configs: [{
type: 'RANGE_DELETE',
parentID: 'client:root',
parentName: 'client:root',
connectionKeys: [{ key: 'Leads_leads' }],
pathToConnection: ['client:root', 'leads'],
deletedIDFieldName: 'deletedLeadId',
}],
});

This is the response I get from the server

{
deleteLeads: {
deletedLeadId:[
"TGVhZDowMjFkYWY4NS02NzFhLTExZTctOTU5OC0wODAwMjAwYzlhNjY=",
"TGVhZDowMjFkZmRhOS02NzFhLTExZTctOTU5OC0wODAwMjAwYzlhNjY=",
]
}
}
```

Most helpful comment

@anttimo Hurray I found the issue!!!!

It was coming from the fact that you need to add a filter to the connectionKey! I found the answer here https://github.com/facebook/relay/issues/1808

@connection(key: "Leads_data") {

to

@connection(key: "Leads_data", filters: []) {

I used the updater function to manually test if I could fetch the connections.

So just adding these little filter brackets removed the uncessessary arguments which enables the connectionHandler to grab the connection

export default function deleteLead(leadIds, onCompleted, onError) {
  commitMutation(relayModernEnvironment, {
    mutation: graphql`
      mutation deleteLeadsMutation($input: DeleteLeadsInput!){
        deleteLeads(input: $input) {
          deletedLeadId
        }
      }
    `,
    variables: {
      input: {
        id: leadIds,
      },
    },
    onError: errors => onError(errors),
    onCompleted: response => onCompleted(response),
    configs: [{
      type: 'RANGE_DELETE',
      parentName: 'client:root',
      parentID: 'client:root',
      connectionKeys: [{
        key: 'Leads_leads',
        rangeBehavior: 'append',
      }],
      pathToConnection: ['client:root', 'leads'],
      deletedIDFieldName: 'deletedLeadId',
    }],
  });
}

All 12 comments

I think you can only delete one node per time, or you should refetch the connection again

maybe this could be achieve easier in Modern

@sibelius Thanks I'll take a look

I think it should be totally fine to delete multiple nodes. Your deletedIDFieldName doesn't seem to match the response you get, maybe that's the issue?

@anttimo Thanks for this that was a type in my issue both names are the same. Any tricks to debug this and see where I'm going wrong?

Sorry, not really. One thing I'm wondering is that should your deletedIDFieldName be a path instead. In this case ['deleteLeads', 'deletedLeadId']. Have you tried this?

@anttimo I just tried doesn't seem to work... I'm a bit confused maybe I'm going wrong in the path to connection parameter. Is there a way to validate these parameter in the log, printing the connection path?

I'm not sure about printing them, might have to go through the Relay source and do it from there. What comes to the path to connection I was also pondering about that. Have you tried just having leads in there? Try that + with and without the change I mentioned earlier.

I've dug into the relayStore debug and this is what I saw:

image

I use a refetch container now I updated the code above. It seems the path includes the arguments!

I haven't used modern Relay yet but have you tried to use the updater function instead of configs? Might be easier to debug possible issues with it. Here is one example I found using it https://github.com/relayjs/relay-examples/blob/master/todo-modern/js/mutations/RemoveCompletedTodosMutation.js

@anttimo Hurray I found the issue!!!!

It was coming from the fact that you need to add a filter to the connectionKey! I found the answer here https://github.com/facebook/relay/issues/1808

@connection(key: "Leads_data") {

to

@connection(key: "Leads_data", filters: []) {

I used the updater function to manually test if I could fetch the connections.

So just adding these little filter brackets removed the uncessessary arguments which enables the connectionHandler to grab the connection

export default function deleteLead(leadIds, onCompleted, onError) {
  commitMutation(relayModernEnvironment, {
    mutation: graphql`
      mutation deleteLeadsMutation($input: DeleteLeadsInput!){
        deleteLeads(input: $input) {
          deletedLeadId
        }
      }
    `,
    variables: {
      input: {
        id: leadIds,
      },
    },
    onError: errors => onError(errors),
    onCompleted: response => onCompleted(response),
    configs: [{
      type: 'RANGE_DELETE',
      parentName: 'client:root',
      parentID: 'client:root',
      connectionKeys: [{
        key: 'Leads_leads',
        rangeBehavior: 'append',
      }],
      pathToConnection: ['client:root', 'leads'],
      deletedIDFieldName: 'deletedLeadId',
    }],
  });
}

Hooray! :)

Is it working in v11 also?

I could make it working correctly with this settings with react-relay v10.1.3.

But when I upgrade react-relay and other related modules to v11.0.0,
the record is not removed from local relay store.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

sgwilym picture sgwilym  路  4Comments

HsuTing picture HsuTing  路  3Comments

rayronvictor picture rayronvictor  路  3Comments

leebyron picture leebyron  路  3Comments

MartinDawson picture MartinDawson  路  3Comments