Skip to content

Instantly share code, notes, and snippets.

@bartoszgolebiowski
Last active November 7, 2021 18:10
Show Gist options
  • Save bartoszgolebiowski/55121323992c7430aa368fcdb2f18d74 to your computer and use it in GitHub Desktop.
Save bartoszgolebiowski/55121323992c7430aa368fcdb2f18d74 to your computer and use it in GitHub Desktop.
URQL query, mutation, subscription
import React, { FormEvent } from "react";
import {
createRequest,
Mutation,
MutationState,
Query,
QueryState,
Subscription,
} from "urql";
const DonationsQuery = `
query Query($orderBy: OrderByParams) {
donations(orderBy: $orderBy) {
id
count
displayName
email
}
}
`;
const variables: QueryVariables = {
field: "count",
direction: "desc",
};
type Query = {
donations: Donation[];
};
type Donation = {
id: number;
count: number;
displayName: string;
email: string;
};
type QueryVariables = {
field: keyof Donation;
direction: "desc" | "asc";
};
type Mutation = {
createDonationInput: Omit<Donation, "id">;
};
const DonationMutation = `
mutation Mutation($createDonationInput: CreateDonationInput!) {
createDonation(createDonationInput: $createDonationInput) {
id
count
displayName
email
}
}
`;
const DonationSubscription = `
subscription Subscription {
totalUpdated {
total
}
}
`;
type Subscription = {
totalUpdated: {
total: number;
};
};
const handleSubscription = (
prev: Subscription | undefined,
response: Subscription
) => {
return response;
};
const CreateDonation = ({
executeMutation,
}: MutationState<Mutation, Mutation>) => {
const handleSubmit = (e: FormEvent) => {
e.preventDefault();
const formData = new FormData(e.target as HTMLFormElement);
executeMutation(
{
createDonationInput: {
count: Number(formData.get("count")),
displayName: String(formData.get("displayName")),
email: "[email protected]",
},
},
{ additionalTypenames: ["Donation"] }
);
};
return (
<form onSubmit={handleSubmit}>
<input type="text" placeholder="Display Name" name="displayName" />
<input type="number" min={1} placeholder="Count" name="count" />
<input type="email" placeholder="Email" name="email" />
<button type="submit">Submit</button>
</form>
);
};
const DonationList = ({
data,
fetching,
error,
}: QueryState<Query, QueryVariables>) => {
if (fetching) return <p>Loading...</p>;
if (error) return <p>Oh no... {error.message}</p>;
if (!data) return <p>No results</p>;
return (
<ul>
{data.donations.map((donation) => (
<li
key={donation.id}
>{`${donation.displayName} - ${donation.count}`}</li>
))}
</ul>
);
};
const context = { additionalTypenames: ["Donation"] };
const App = () => {
return (
<>
<Mutation<Mutation, Mutation> {...createRequest(DonationMutation)}>
{(props) => <CreateDonation {...props} />}
</Mutation>
<Query<Query, QueryVariables>
{...createRequest(DonationsQuery, variables)}
context={context}
>
{(props) => <DonationList {...props} />}
</Query>
<Subscription<Subscription, Subscription>
{...createRequest(DonationSubscription)}
handler={handleSubscription}
>
{(props) => <h1>{props.data?.totalUpdated?.total ?? 0}</h1>}
</Subscription>
</>
);
};
export default App;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment