peresleguine
peresleguine

Reputation: 2403

Client-side mutation with RANGE_ADD type doesn't include edge inside request payload

I'm trying to create new object using client-side mutation described below:

import Relay from 'react-relay'

export default class CreateThemeMutation extends Relay.Mutation {

  static fragments = {
    admin: () => Relay.QL`fragment on Admin { id }`,
  };

  getMutation() {
    return Relay.QL`mutation { createTheme }`
  }

  getFatQuery() {
    return Relay.QL`
      fragment on CreateThemePayload {
        admin { themes }
        themeEdge
      }
    `
  }

  getVariables() {
    return {
      name: this.props.name,
    }
  }

  getConfigs() {
    return [{
      type: 'RANGE_ADD',
      parentName: 'admin',
      parentID: this.props.admin.id,
      connectionName: 'themes',
      edgeName: 'themeEdge',
      rangeBehaviors: {
        '': 'append',
      },
    }]
  }

}

Root query field admin is quite similar to viewer so this shouldn't be a problem. The problem is I haven't found themeEdge (which I believe should present) within the request payload (admin { themes } is there though):

query: "mutation CreateThemeMutation($input_0:CreateThemeInput!){createTheme(input:$input_0){clientMutationId,...F3}} fragment F0 on Admin{id} fragment F1 on Admin{id,...F0} fragment F2 on Admin{_themes2gcwoM:themes(first:20,query:""){count,pageInfo{hasNextPage,hasPreviousPage,startCursor,endCursor},edges{node{id,name,createdAt},cursor}},id,...F1} fragment F3 on CreateThemePayload{admin{id,...F0,id,...F2}}"
variables: {input_0: {name: "test", clientMutationId: "0"}}

As a result outputFields.themeEdge.resolve inside the server-side mutation never get called and I see this message:

Warning: writeRelayUpdatePayload(): Expected response payload to include the newly created edge `themeEdge` and its `node` field. Did you forget to update the `RANGE_ADD` mutation config?

I've seen similar issue on github. However REQUIRED_CHILDREN isn't my case because the application has requested themes connection already. Am I missing something obvious? Should I paste more info? Thanks.

react-relay version: 0.6.1

Upvotes: 2

Views: 346

Answers (1)

jbrown
jbrown

Reputation: 7996

I ran into the same issue and eventually solved it by making sure that my equivalent of themeEdge actually existed as an edge in my schema. If you grep your schema for themeEdge, does an object exist?

For reference, here's my edge definition tailored for you:

{
      "name":"themeEdge",
      "description":null,
      "args":[],
      "type":{
        "kind":"NON_NULL",
        "name":null,
        "ofType":{
          "kind":"OBJECT",
          "name":"ThemeEdge",
          "ofType":null
        }
      },
      "isDeprecated":false,
      "deprecationReason":null
    }

and

{
    "kind":"OBJECT",
    "name":"ThemeEdge",
    "description":"An edge in a connection.",
    "fields":[{
      "name":"node",
      "description":"The item at the end of the edge.",
      "args":[],
      "type":{
        "kind":"NON_NULL",
        "name":null,
        "ofType":{
          "kind":"OBJECT",
          "name":"Theme",
          "ofType":null
        }
      },
      "isDeprecated":false,
      "deprecationReason":null
    }

Also note that your rangeBehaviors must exactly match the query you use to retrieve your parent object. You can specify multiple queries as follows, which also shows the syntax for when your query contains multiple variables:

{
    type: 'RANGE_ADD',
    parentName: 'admin',
    parentID: this.props.admin.id,
    connectionName: 'themes',
    edgeName: 'themeEdge',
    rangeBehaviors: {
      '': 'append',
      'first(1).id($adminId)': 'append',
    },
  }

Upvotes: 1

Related Questions