Skip to content

Instantly share code, notes, and snippets.

@wbyoung
Created March 17, 2018 23:18
Show Gist options
  • Save wbyoung/f4ef16828ea1f4b0071bcf3eb27335e5 to your computer and use it in GitHub Desktop.
Save wbyoung/f4ef16828ea1f4b0071bcf3eb27335e5 to your computer and use it in GitHub Desktop.
/* @flow */
import React, { type Element } from 'react';
import Relay from 'react-relay/classic';
class CreateListMutation extends Relay.Mutation {
static fragments = {
viewer: () => Relay.QL`
fragment on User {
id
}
`,
};
getMutation(): any {
return Relay.QL`mutation{createList}`;
}
getVariables(): any {
return {
name: this.props.name,
};
}
getFatQuery(): any {
return Relay.QL`
fragment on CreateListPayload {
viewer { lists }
newListEdge
}
`;
}
getConfigs(): any {
return [{
type: 'RANGE_ADD',
parentName: 'viewer',
parentID: this.props.viewer.id,
connectionName: 'lists',
edgeName: 'newListEdge',
rangeBehaviors: {
'': 'append',
},
}];
}
}
class Lists extends React.Component<*> {
componentDidMount() {
(async (): Promise<void> => {
// wait just a second so that its clear if anyone runs this that the data
// isn't all being fetched right away & instead is being fetched after the
// setVariables call.
await new Promise((resolve: () => void) => setTimeout(resolve, 1000));
// set variables to actually fetch the connection via a second definition
// that includes more fields/data. this should be tracked just as the
// first request for data tracked the full connection query (node), but in
// this case, the setting of variables should not issue a new client
// request since the connection's arguments have not changed (and
// therefore the connection will not have new edges since it's assumed to
// be stable).
await new Promise((resolve: () => void) => {
this.props.relay.setVariables({
detailedConnection: true,
}, resolve);
});
// run a mutation so that a new edge is created in the connection. if
// handled properly, the second fragment will be tracked and the mutation
// query will include this fragment as well.
const mutation = new CreateListMutation({
viewer: this.props.viewer,
name: 'Test',
});
await new Promise((
resolve: () => void,
reject: (Error) => void,
) => {
this.props.relay.commitUpdate(mutation, {
onSuccess: resolve,
onFailure: (transaction: *) => {
reject(transaction.getError() || new Error('Unknown error.'));
},
});
});
})();
}
render(): Element<any> {
if (!this.props.relay.variables.detailedConnection) {
return (<div>waiting for second query to complete</div>);
}
// owner should always be included when relay queries for data, but this
// acutally does not fetch the owner & instead displays the failure text
// after the mutation completes.
const listOwners = this.props.viewer.lists.edges.map((edge: *) => (
<div key={ edge.node.id }>
{
edge.node.owner ? edge.node.owner.name : 'RELAY FAILURE'
}
</div>
));
return (
<div>
{ listOwners }
</div>
);
}
}
export default Relay.createContainer(Lists, {
initialVariables: {
detailedConnection: false,
},
fragments: {
viewer: () => Relay.QL`
fragment on User {
id
lists(first: 10) @include(if: $detailedConnection) {
edges {
node {
id
owner {
name
}
}
}
}
lists(first: 10) {
edges {
node {
id
}
}
}
}
`,
},
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment