Relay: RANGE_ADD does not query for newly created edge

Created on 16 Oct 2015  路  14Comments  路  Source: facebook/relay

I have the following mutation

static fragments = {
    hackRoot: () => Relay.QL`
      fragment on HackRoot {
        id        
    }
    `,
  };
  getMutation() {
    return Relay.QL`mutation{addGame}`;
  }
  getFatQuery() {
    return Relay.QL`
      fragment on AddGamePayload {  
        hackRoot{
          gamesForPlayerOrCity( cityOrId:"Almaty"){
            totalCount
          }
        } 
        gameEdge

      }
    `;
  }
  getConfigs() {
    console.log('adding range')
    return [{
      type: 'RANGE_ADD',
      parentName: 'hackRoot',
      parentID: this.props.hackRoot.id,
      connectionName: 'gamesForPlayerOrCity',
      edgeName: 'gameEdge',
      rangeBehaviors: {
        '': 'append',
      },
    }];
  }
  getVariables() {
    return {
      playersCount: this.props.playersCount,
      time: this.props.time,
      idHost:this.props.idHost,
      city:this.props.city
    };
  }
}

The query that it generates does not include gameEdge:

mutation AddGameMutation($input:AddGameInput!){
    addGame(input:$input){
        clientMutationId,...__RelayQueryFragment5r4pce9
    }
} 
fragment __RelayQueryFragment5r4pce9 on AddGamePayload{
    hackRoot{
        _gamesForPlayerOrCityw0m0wi:gamesForPlayerOrCity(first:100,cityOrId:"Almaty"){
            totalCount
        },
        id
    }
}

and i get the 'Warning: writeRelayUpdatePayload(): Expected response payload to include the newly created edge gameEdge and its node field. Did you forget to update the RANGE_ADD mutation config?' error.

I simulated mutation via graphiql and it correctly responds with newly created edge:
screen shot 2015-10-16 at 8 08 35 pm

Why doesn't Relay include gameEdge into query? it isn't subtracted as the app requests for the data, what other issue might be causing this error

Most helpful comment

I see the same behavior as @mickeyinfoshan in regards to the warning. For example, I see the warning if my query fragment looks like this:

purchases(first: 100, status: $status) { ... }

The warning does not appear if I change my query to this:

purchases(first: 100) { ... }

If my rangeBehaviors look like this then I see the warning when using both the first and status arguments:

rangeBehaviors: {
  '': 'append',
  'first()': 'append',
  'status()': 'append',
}

However, if I update my rangeBehaviors so that they match the default values set in the schema, the warning goes away and everything works as expected. For example:

// AddPurchaseMutation.js
rangeBehaviors: {
  '': 'append',
  'first()': 'append',
  'status(all)': 'append',
}

// schema.go
Args: relay.NewConnectionArgs(graphql.FieldConfigArgument{
    "status": &graphql.ArgumentConfig{
        DefaultValue: "all",
    },
}),

It feels right to me that the rangeBehaviors should specify status(all) and not status() because "all" is my default value. It was easy to miss though. I hope this helps someone!

All 14 comments

Have same problem, seems like a bug to me

Have the same problem.

confirmed.

Does something in your application query for the gamesForPlayerOrCity connection on the applicable hackRoot object?

In my case, connection isn't queried before mutation.

yes the games component asks for it in its container

export default Relay.createContainer(Games, {
    initialVariables:{
        count:100,
        idOrCity:null,
        endCursor:null

    },
  fragments: {

    hackRoot: () => 

        Relay.QL`
      fragment on HackRoot {
        ${AddGameMutation.getFragment('hackRoot')}
        gamesForPlayerOrCity(first:$count after:$endCursor cityOrId:$idOrCity){
            totalCount
            pageInfo{
                hasNextPage
                endCursor
            }
            edges{
                node{

                    playersCount
                      time
                      id
                      createdAt
                      addressLine,
                      hostId
                      timeAfterParse,
                      dateAfterParse

                      hostName
                      hostImageURL
                      price
                      idServer
                }
                cursor
            }
        }
      }
    `,

  }
})

Having same issue with
"react-relay": "^0.4.0",

I had the same problem, until I realized the issue comes from not including a proper getOptimisticResponse() definition in the client side mutation. So for the above example, something like this would eliminate the warning:

    getOptimisticResponse() {
       return {
          gameEdge: {
             node: {
                playersCount: this.props.playersCount,
                hostId: this.props.hostId
                //Other node fields defined by input variables  
            },
          },
          hackRoot: {
             id: this.props.hackRoot.id
          },
       };
     }

merging into #542

REQUIRED_CHILDREN can be used to ensure that the new edge field is included in the mutation query.

That said, I am not sure that querying for the connection before the mutation actually does include the new edge field in the mutation! Can somebody confirm this? Because鈥攚hy would the querying the connection include the new edge field in the tracked query, given that the connection field is not the same as the edge field?

I still have this issue.
I almost copied the example code from here and I get a warning: warrning: writeRelayUpdatePayload(): Expected response payload to include the newly created edgetodoEdgeand itsnodefield. Did you forget to update theRANGE_ADDmutation config?

Here's my code:

class AddTodo extends Relay.Mutation {

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

    getMutation() {
        return Relay.QL`mutation{
            addTodo
        }`;
    }

    getVariables() {
        return {text : this.props.text}
    }

    getFatQuery () {
        return Relay.QL`
            fragment on AddTodo {
                todoEdge,
                viewer {
                    todos,
                    totalCount,
                }
            }
        `
    }

    getConfigs() {
        return [{
            type : "RANGE_ADD",
            parentName : "viewer",
            parentID : this.props.viewer.id,
            connectionName : "todos",
            edgeName : "todoEdge",
            rangeBehaviors : {
                '' : 'append'
            }
        }]
    }

     getOptimisticResponse() {
       return {
          todoEdge: {
             node: {
                text : this.props.text,
                completed : false 
            },
          },
          viewer: {
             totalCount: this.props.viewer.totalCount + 1,
             id : this.props.viewer.id
          },
       };
     }
}

I'm sure my graphql works. Do I miss something?

Hmm..
I've figured out that it's variables that causes this issue in my case.
For example:

todos(first:$limit){
  ...
}

will work as what I expect, but

todos(first:$limit, completed:false){
  ...
}

will cause such issue.

I don't know why.

I see the same behavior as @mickeyinfoshan in regards to the warning. For example, I see the warning if my query fragment looks like this:

purchases(first: 100, status: $status) { ... }

The warning does not appear if I change my query to this:

purchases(first: 100) { ... }

If my rangeBehaviors look like this then I see the warning when using both the first and status arguments:

rangeBehaviors: {
  '': 'append',
  'first()': 'append',
  'status()': 'append',
}

However, if I update my rangeBehaviors so that they match the default values set in the schema, the warning goes away and everything works as expected. For example:

// AddPurchaseMutation.js
rangeBehaviors: {
  '': 'append',
  'first()': 'append',
  'status(all)': 'append',
}

// schema.go
Args: relay.NewConnectionArgs(graphql.FieldConfigArgument{
    "status": &graphql.ArgumentConfig{
        DefaultValue: "all",
    },
}),

It feels right to me that the rangeBehaviors should specify status(all) and not status() because "all" is my default value. It was easy to miss though. I hope this helps someone!

@piinecone You do help me a lot! Thank you.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

sibelius picture sibelius  路  3Comments

johntran picture johntran  路  3Comments

jstejada picture jstejada  路  3Comments

HsuTing picture HsuTing  路  3Comments

bondanherumurti picture bondanherumurti  路  3Comments