Rax Wunter
Rax Wunter

Reputation: 2787

Relay mutation fragments intersection

I don't use Relay container, because I'd like to have more control over components. Instead of it I use HOC + Relay.Store.forceFetch, that fetches any given query with variables. So I have the following query:

query {
    root {
      search(filter: $filter) {
        selectors {
          _id,
          data {
            title,
            status
          }
        },
        selectorGroups {
          _id,
          data {
            title,
          }
        }
      }
  }
}

Then I have to do some mutation on selector type.

export default class ChangeStatusMutation extends Relay.Mutation {
  getMutation() {
    return Relay.QL`mutation {selectors_status_mutation}`;
  }
  getVariables() {
    return {
      id: this.props.id,
      status: this.props.status
    };
  }
  getFatQuery() {
    return Relay.QL`
      fragment on selectors_status_mutationPayload{
        result {
          data {
            status
          }
        }
      }
    `;
  }
  static fragments = {
    result: () => Relay.QL`
      fragment on selector {
        _id,
        data {
          title,
          status
        }
      }`,
  };

  getOptimisticResponse() {
    return {
      result: {
        _id: this.props.id,
        data: {
          status: this.props.status
        }
      }
    };
  }

  getConfigs() {
    return [{
      type: 'FIELDS_CHANGE',
      fieldIDs: {
        result: this.props.id
      },
    }];
  }
}

Call mutation in component:

const mutation = new ChangeStatusMutation({id, status, result: selector});
Relay.Store.commitUpdate(mutation);

After mutation commitment selector in Relay storage is not changed. I guess that's because of empty Tracked Fragment Query and mutation performs without any fields:

ChangeStatusMutation($input_0:selectors_statusInput!) {
  selectors_status_mutation(input:$input_0) {
    clientMutationId
  }
}

But the modifying selector was already fetched by Relay, and I pass it to the mutation with props. So Relay knows the type, that should be changed, how to find the item and which fields should be replaced. But can not intersect. What's wrong?

Upvotes: 0

Views: 587

Answers (1)

NevilleS
NevilleS

Reputation: 1209

So, you're definitely a bit "off the ranch" here by avoiding Relay container, but I think this should still work...

Relay performs the query intersection by looking up the node indicated by your FIELDS_CHANGE config. In this case, your fieldIDs points it at the result node with ID this.props.id.

Are you sure you have a node with that ID in your store? I'm noticing that in your forceFetch query you fetch some kind of alternative _id but not actually fetching id. Relay requires an id field to be present on anything that you later want to refetch or use the declarative mutation API on...

I'd start by checking the query you're sending to fetch whatever this result type is. I don't see you fetching that anywhere in your question description, so I'm just assuming that maybe you aren't fetching that right now?

Upvotes: 1

Related Questions