[EDIT] See my answer below.
In our react-native app, we're using GraphQL Code Generator (GCG) to generate GraphQL queries and mutations from our schema and local GraphQL files. Below is the generates section of our codegen.yml
file.
generates:
src/generated/graphql.tsx:
plugins:
- "typescript"
- "typescript-operations"
- "typescript-react-apollo"
config:
withResultType: true
withHOC: false
withHooks: true
withComponent: false
withMutationFn: false
./graphql.schema.json:
plugins:
- "introspection"
Queries are very straightforward in how they are called and data is accessed.
Mutations, however, have become a blocker for us.
Here is the graphql that GraphQL Code Generator is processing:
mutation GetPaymentUrl(
$account_number: String!
$role: String!
$pay_my_bill: Boolean
$mortgageeBillIndicator: Boolean
$requested_by: String!
) {
getIncPaymentUrl(
input: {
account_number: $account_number
role: $role
pay_my_bill: $pay_my_bill
mortgageeBillIndicator: $mortgageeBillIndicator
requested_by: $requested_by
}
) {
account_number
payment_portal_redirect_url
}
}
Here is the code generated by GCG:
export type Mutation = {
__typename?: 'Mutation';
getIncPaymentUrl?: Maybe<IncResponse>;
};
export type MutationGetIncPaymentUrlArgs = {
input?: Maybe<IncPaymentRequestUrl>;
};
export type IncPaymentRequestUrl = {
account_number: Scalars['String'];
role: Scalars['String'];
pay_my_bill?: Maybe<Scalars['Boolean']>;
mortgageeBillIndicator?: Maybe<Scalars['Boolean']>;
requested_by: Scalars['String'];
};
export type IncResponse = {
__typename?: 'IncResponse';
account_number?: Maybe<Scalars['String']>;
payment_portal_redirect_url?: Maybe<Scalars['String']>;
};
export type GetPaymentUrlMutationVariables = Exact<{
account_number: Scalars['String'];
role: Scalars['String'];
pay_my_bill?: Maybe<Scalars['Boolean']>;
mortgageeBillIndicator?: Maybe<Scalars['Boolean']>;
requested_by: Scalars['String'];
}>;
export type GetPaymentUrlMutation = {__typename?: 'Mutation'} & {
getIncPaymentUrl?: Maybe<
{__typename?: 'IncResponse'} & Pick<
IncResponse,
'account_number' | 'payment_portal_redirect_url'
>
>;
};
export const GetPaymentUrlDocument = gql`
mutation GetPaymentUrl(
$account_number: String!
$role: String!
$pay_my_bill: Boolean
$mortgageeBillIndicator: Boolean
$requested_by: String!
) {
getIncPaymentUrl(
input: {
account_number: $account_number
role: $role
pay_my_bill: $pay_my_bill
mortgageeBillIndicator: $mortgageeBillIndicator
requested_by: $requested_by
}
) {
account_number
payment_portal_redirect_url
}
}
`;
/**
* __useGetPaymentUrlMutation__
*
* To run a mutation, you first call `useGetPaymentUrlMutation` within a React component and pass it any options that fit your needs.
* When your component renders, `useGetPaymentUrlMutation` returns a tuple that includes:
* - A mutate function that you can call at any time to execute the mutation
* - An object with fields that represent the current status of the mutation's execution
*
* @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2;
*
* @example
* const [getPaymentUrlMutation, { data, loading, error }] = useGetPaymentUrlMutation({
* variables: {
* account_number: // value for 'account_number'
* role: // value for 'role'
* pay_my_bill: // value for 'pay_my_bill'
* mortgageeBillIndicator: // value for 'mortgageeBillIndicator'
* requested_by: // value for 'requested_by'
* },
* });
*/
export function useGetPaymentUrlMutation(
baseOptions?: Apollo.MutationHookOptions<
GetPaymentUrlMutation,
GetPaymentUrlMutationVariables
>,
) {
return Apollo.useMutation<
GetPaymentUrlMutation,
GetPaymentUrlMutationVariables
>(GetPaymentUrlDocument, baseOptions);
}
export type GetPaymentUrlMutationHookResult = ReturnType<
typeof useGetPaymentUrlMutation
>;
export type GetPaymentUrlMutationResult = Apollo.MutationResult<GetPaymentUrlMutation>;
export type GetPaymentUrlMutationOptions = Apollo.BaseMutationOptions<
GetPaymentUrlMutation,
GetPaymentUrlMutationVariables
>;
When I examine getPaymentUrlMutation
from my example above, I don't see the mutate function documented in the generated code. I do see "call", "apply", and "bind" methods.
I'm not clear on where/how to call this mutation.
I've found that if I call getPaymentUrlMutation.call({})
before the return in my tsx file, I get an infinite loop of requests.
If I call it like the following in the return...
<ButtonStyle
onPress={() => {
getPaymentUrlMutation.call({}).then((r) =>
OnPayment(
r.data?.getIncPaymentUrl?.payment_portal_redirect_url,
),
);
}}>
<PayButtonStyle>pay now</PayButtonStyle>
</ButtonStyle>
... I don't have an opportunity to handle errors. Plus, as @xadm notes, it doesn't seem "right" from a react standpoint.
How should I execute the mutation in the context of an onPress event for a react-native button?