2

This is a follow-up question to this answer posted earlier on SO about a react-relay mutation warning.

"In you case what you have to do is to add the FeatureLabelNameMutation getFragment to your AddCampaignFeatureLabelMutation query."

As with the OP in that question, I too want to make a nested relay mutation and I've tried doing what @Christine is suggesting, but I'm uncertain on where exactly to put the getFragment part.

In my application, I want to create a "task" with multiple nested "sub-tasks" when the user creates a task.

What I have tried works, but I don't get the returned PayLoad for the AddSubTaskMutation mutation. Here's what I've tried so far:

AddTaskMutation.js

export default class AddTaskMutation extends Relay.Mutation {
  static fragments = {
    classroom: () => Relay.QL`
      fragment on Classroom { 
        id,
        tasks(last: 1000) {
          edges {
            node {
                id,
                ${AddSubTaskMutation.getFragment('task')}, //<-- what I tried adding 
            },
          }
        },
      }`,
    }`,
  };
  ...

AddSubTaskMutation.js

export default class AddSubTaskMutation extends Relay.Mutation {
  static fragments = {
    task: () => Relay.QL`
      fragment on Task { 
        id,
      }`,
   };
   ...

TaskCreate.js

Relay.Store.update(
  new AddTaskMutation({
    title,
    instruction,
    start_date,
    end_date,
    published: isPublished,
    classroom: this.props.classroom
  }),
  {
    onSuccess: (response) => {
      let {taskEdge} = response.addTask;
      for (let subTask of this.state.subTaskContent) {
        Relay.Store.update(
          new AddSubTaskMutation({
            task: taskEdge.node,
            type: subTask['type'],
            position: subTask['position'],
            ...
          }),
        );
      }
    }
  }
)
...
export default Relay.createContainer(TaskCreate, {
  prepareVariables() {
    return {
      limit: Number.MAX_SAFE_INTEGER || 9007199254740991,
    };
  },
  fragments: {
    classroom: () => Relay.QL`
      fragment on Classroom {
        id,
        tasks(last: $limit) {
          edges {
            node {
              id,
              ...
            }   
          }
        },
        ...
        ${AddTaskMutation.getFragment('classroom')},
      }
    `,
  },
});

Apart from not getting the payload, I'm also getting the following warnings:

Warning: RelayMutation: Expected prop `task` supplied to `AddSubTaskMutation` to be data fetched by Relay. This is likely an error unless you are purposely passing in mock data that conforms to the shape of this mutation's fragment.
Warning: writeRelayUpdatePayload(): Expected response payload to include the newly created edge `subTaskEdge` and its `node` field. Did you forget to update the `RANGE_ADD` mutation config?

So my question is: where do i add the getFragment in AddTaskMutation.js to make this work?

1
  • Using getFragment for a mutation is somewhat uncommon - it's only needed when the mutation itself needs additional data before the mutation executes. It's a bit weird, then, to see your mutation requesting up to 1000 other tasks, when you really just want to add a new one. Are you using any of that data for the mutation itself? Commented Feb 6, 2016 at 23:50

1 Answer 1

1

From what I can tell, the issue is that you don't really understand what the mutation "fragment" is for vs. the rest of the mutation properties (fat query & configs). The warning you are seeing is related to Relay noticing that the task prop you are giving it isn't from the AddSubtaskMutation fragment, it's from the AddTaskMutation mutation query. But that's really just a red herring; your issue is that you don't need those fragments at all, you just need to configure the mutation appropriately to create your new nodes & edges. Here's a couple suggestions.

Step #1

  • Get rid of the fragments in both AddTaskMutation and AddSubtaskMutation, they seem unnecessary
  • Modify AddTaskMutation's constructor to take a bunch of fields for the task and a classroomID to specify the affected classroom
  • Similarly, modify AddSubTaskMutation to take a bunch of fields for the subtask and a taskID to specify the parent task
  • Make sure your AddTaskMutation payload includes the modified classroom and the new task edge
  • Define a RANGE_ADD mutation using the classroomID to target the classroom for the new task
  • Define a FIELDS_CHANGE mutation on AddSubtaskMutation that mutates the parent using the given taskID (I'm not sure how you're storing subtasks, probably a connection). You can change this to a RANGE_ADD if you really want.

Step #2: Simplify

  • It seems unnecessary to do this in 1+N mutations (N subtasks), when you seem to have all the information at the start. I'd modify the input of AddTaskMutation to accept a new task and an array of subtasks, and do it all at once...
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for your input! I'll test these suggestions at work tomorrow morning and will come back to you. Many thanks again!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.