How to specify edges with arguments in mutation's fat query - relayjs

According to this answer it should be possible to specify edges with arguments in fat query, but I can't make it work. Here are is my mutation config and fat query:
getFatQuery() {
return Relay.QL`
fragment on AddCommentPayload {
commentEdge(sort:[{createdAt: ASC}])
customer {
id
comments
}
}
`;
}
getConfigs() {
return [{
type: 'RANGE_ADD',
parentName: 'customer',
parentID: this.props.customer.id,
connectionName: 'comments',
edgeName: 'commentEdge',
rangeBehaviors() {
return 'append';
},
}];
}
Problem is that resulting query doesn't contain any arguments on edge field:
mutation AddComment($input_0:AddCommentInput!) {
addComment(input:$input_0) {
clientMutationId,
...F1
}
}
fragment F0 on Customer {
id
}
fragment F1 on AddCommentPayload {
commentEdge {
cursor,
__typename,
node {
id,
createdAt,
commentText
}
},
customer {
id,
...F0
}
}

Related

How to force refetch the entire node in Relay?

Suppose that we have this mutation:
const [addCryptoAddress] =
useMutation(graphql`
mutation useCrypto_AddCryptoWalletAddressMutation(
$input: AddCryptoAddressInput!
) {
addCryptoAddress(input: $input) {
userAccount {
cryptoCurrencyAddresses {
count
edges {
node {
id
address
}
}
}
}
errors {
message
}
}
}
`);
If successful, a new CryptoCurrencyAddresses will be available under UserAccount.
Now suppose that somewhere else in the code we have a lazyLoadQuery that fetches these addresses, e.g.
const { visitor } = useLazyLoadQuery<ManualPayoutMachineContextQuery>(
graphql`
query ManualPayoutMachineContextQuery {
visitor {
userAccount {
cryptoCurrencyAddresses {
edges {
node {
id
address
canDelete
currency
isDefault
label
}
}
}
}
}
}
`,
{}
);
However, note that this query references additional fields that are not mentioned in the mutation. The result is that all unmentioned fields are undefined immediately after the mutation, i.e.
visitor.userAccount?.cryptoCurrencyAddresses.edges
.map(({ node }) => {
return {
address: node.address,
canDelete: node.canDelete,
currency: node.currency,
id: node.id,
isDefault: node.isDefault,
label: node.label,
};
});
Produces:
[
{
address: '0xc0ffee254729296a45a3885639AC7E10F9d54979',
canDelete: undefined,
currency: undefined,
id: 'WyJDcnlwdG9DdXJyZW5jeUFkZHJlc3MiLDIwMjE3NF0=',
isDefault: undefined,
label: undefined,
}
]
Apart from listing every overlapping field in the mutation, is there a way to force all queries that depend on this data to reload when they detect new data?
You can set fetchPolicy as store-and-network, like this:
const { visitor } = useLazyLoadQuery<ManualPayoutMachineContextQuery>(
graphql`
query ManualPayoutMachineContextQuery {
visitor {
userAccount {
cryptoCurrencyAddresses {
edges {
node {
id
address
canDelete
currency
isDefault
label
}
}
}
}
}
}
`,
{},
{
fetchPolicy: 'store-and-network',
}
);
The store-and-network will use the data of the store and always do a network request without making regardless.

How to write relationship mutation in GraphQL using GRANDstack?

I am trying to create a relationship between to nodes in Neo4j using GraphQL. What should the mutation look like?
Schema shows it should look like this.
AddPersonRoll(
from: _PersonInput!
to: _RollInput!
): _AddPersonRollPayload
I tryed
mutation {
AddPersonRoll(
from: {
id: "be91aaca-944d-49f7-b3fd-c89ad454d5ab"
}
to: {
id: "8726255f-b6b6-4299-ba01-95f6d4ef2be7"
}
) {
from {
id
name
}
to {
id
name
}
}
}
And it worked. But when I tried putting var into the query I got
{
"error": "Failed to execute 'fetch' on 'Window': Invalid name"
}
the code is
mutation AddPersonRoll($PersonInput: ID!, $RollInput: ID!){
AddPersonRoll(
from: {
id: $PersonInput
}
to: {
id: $RollInput
}
) {
from {
id
name
}
to {
id
name
}
}
}
{
"PersonInput": "3cc70aca-9e07-4bbd-acb2-92670b4d1b0d",
"RollInput": "8726255f-b6b6-4299-ba01-95f6d4ef2be7"
}
Found this earlier today when I ran into a similar problem. Here is my working mutation:
const ADD_INCIDENT_USER = gql`
mutation AddIncidentUser($from: ID!, $to: ID!) {
AddIncidentUser(from: { id: $from }, to: { id: $to }) {
from {
id
}
to {
id
}
}
}
`;
so in your example you would want to change
mutation AddPersonRoll($PersonInput: ID!, $RollInput: ID!){
to
mutation AddPersonRoll($from: ID!, $to: ID!){

Modern Relay - ConnectionConfig for multiple connections

EDIT: after some research I found out that ReactRelayPaginationContainer does only support one #connection for now (relay release 1.0.0).
I am not sure how to deal with multiple Connections in a PaginationContainer using Relay Modern as the only examples I saw so far only included one Connection. To illustrate my concern, there is some code below where I am having troubles
export default createPaginationContainer(MyComponent,
{
item: graphql`fragment mycomponent_item on Item {
foos(first: $count_foo, after: $cursor_foo) #connection(key: item_foos) {
pageInfo {
hasNextPage
endCursor
}
edges {
node {
id
...foo_foo
}
}
}
bars(first: $count_bar, cursor: $cursor_bar) #connection(key: item_bars) {
pageInfo {
hasNextPage
endCursor
}
edges {
node {
id
...bar_bar
}
}
}
}
}`
},
{
direction: 'forward',
getConnectionFromProps(props) {
return props.item.foos && props.item.bars;
},
getFragmentVariables(prevVars, totalCount) {
return {
...prevVars,
count: totalCount,
};
},
getVariables(props, {count, cursor}, fragmentVariables) {
return {
count,
cursor,
};
},
query: graphql`
query itemPaginationQuery(
$count_foo: Int!
$cursor_foo: String
$count_bar: Int!
$cursor_bar: String
) {
Item {
... mycomponent_item
}
}
`
});
The problem is in the ConnectionConfig of PaginationContainer of Relay Modern:
export type ConnectionConfig = {
direction?: 'backward' | 'forward',
getConnectionFromProps?: (props: Object) => ?ConnectionData,
getFragmentVariables?: FragmentVariablesGetter,
getVariables: (
props: Object,
paginationInfo: {count: number, cursor: ?string},
fragmentVariables: Variables,
) => Variables,
query: GraphQLTaggedNode,
};
It is clearly made just for one Connection in the PaginationContainer. And createPaginationContainer only accepts one of such ConnectionConfigs in it's constructor.
How am I supposed to deal with multiple Connections in one PaginationContainer?

RelayMutation expects prop to be data fetched by Relay, adding mutation to query not working

I am getting the error:
bundle.js:28169 Warning: RelayMutation: Expected prop `group` supplied to `AddBlock` 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.
It might seem similar to the problem described in this question, but the answer (of making sure the mutation is added to the initial query) is not working as a solution for me. I already have the mutation in the original query.
Here is my relevant code:
export class AddBlock extends Relay.Mutation {
getMutation() {
return Relay.QL`mutation { addBlock }`;
}
getVariables() {
return {
body: this.props.body
};
}
getFatQuery() {
return Relay.QL`
fragment on AddBlock {
newBlockEdge,
group {
blocks
}
}
`;
}
getConfigs() {
return [{
type: 'RANGE_ADD',
parentName: 'group',
parentID: this.props.group.id,
connectionName: 'blocks',
edgeName: 'newBlockEdge',
rangeBehaviors: {
'': 'append',
},
}];
}
getOptimisticResponse() {
return {
newBlockEdge: {
node: {
body: this.props.body
}
},
group: {
id: this.props.group.id
}
}
}
static get fragments() {
return {
group: () => Relay.QL`
fragment on GroupNode {
id
}
`,
}
}
}
class Designer extends React.Component {
...
addToBlocks(blocks) {
// Create a mutation to save to the blocks.
Relay.Store.commitUpdate(
new AddBlock({
body: blocks[0].block,
group: this.props.group
})
);
}
...
}
Designer = Relay.createContainer(Designer, {
fragments: {
group: (Component) => Relay.QL`
fragment on GroupNode {
title
visibility
blocks(first: 20) {
edges {
node {
${Block.getFragment('block')}
${UpdateBlockBodyMutation.getFragment('block')}
position
title
}
}
}
${AddBlock.getFragment('group')}
}
`,
}
});
What could I be doing wrong here?
I suspect your mutation fragment isn't actually being used - you should run a test to see that if you add other fields to the AddBlock fragment, you'll find that they aren't being requested...? I'm not 100% sure why (likely something about static get fragments), but not quite sure.
Once you get your mutation fragment actually being used, Relay won't complain anymore since it'll be getting data in the correct way :D

Multiple Mutations on a single object

I try to have a addColumn and a removeColumn mutation on a Chart component.
But when I call
Relay.Store.commitUpdate(new RemoveChartColumnMutation({
chart: this.props.viewer.chart,
column: this.props.viewer.chart.columns[0]
})
I get this error
"Fragment \"F2\" cannot be spread here as objects of type "AddChartColumnPayload\" can never be of type \"RemoveChartColumnPayload\"."
What am I doing wrong here?
export default Relay.createContainer(Home, {
fragments: {
viewer: () => Relay.QL`
fragment on User {
chart {
columns
${AddChartColumnMutation.getFragment('chart')}
${RemoveChartColumnMutation.getFragment('chart')}
}
}`
}
});
With these mutations
class AddChartColumnMutation extends Relay.Mutation {
getMutation() {
return Relay.QL`mutation {addChartColumn}`;
}
getVariables() {
return {
id: this.props.chart.id,
key: this.props.key,
aggregation: this.props.aggregation
};
}
getFatQuery() {
return Relay.QL`
fragment on AddChartColumnPayload {
chart {
columns
}
}
`;
}
getConfigs() {
return [{
type: 'FIELDS_CHANGE',
fieldIDs: {
chart: this.props.chart.id
}
}];
}
static fragments = {
chart: () => Relay.QL`
fragment on Chart {
id
type
}
`
};
}
and
class RemoveChartColumnMutation extends Relay.Mutation {
getMutation() {
return Relay.QL`mutation {addChartColumn}`;
}
getVariables() {
return {
chartId: this.props.chart.id,
columnId: this.props.column.id
};
}
getFatQuery() {
return Relay.QL`
fragment on RemoveChartColumnPayload {
chart {
columns
}
}
`;
}
getConfigs() {
return [{
type: 'FIELDS_CHANGE',
fieldIDs: {
chart: this.props.chart.id
}
}];
}
static fragments = {
chart: () => Relay.QL`
fragment on Chart {
id
type
}
`
};
}
I think you've just got a typo in your code. Looks like both mutations are calling the addChartColumn mutation, which would explain the error expecting the remove chart column payload.

Resources