The app
- backend keystone server
- frontend next app
- using Apollo Client to work GraphQL magic.
It's an ecommerce store where the client can do all CRUD application in the NextJS app.
The Problem
Uploading an image to Keystone's local storage (through the NextJS app) is tough.
My Code
CreateProduct.tsx
import useForm from "@/lib/useForm"
import { gql, useMutation } from "@apollo/client"
import ErrorMessage from "../ErrorMessage"
export const ProductCreate = () => {
const {inputs, handleChange, clearForm, resetForm} = useForm({
image: '',
name: 'new product',
price: 123,
})
const [createProduct, {loading, error, data}] = useMutation(
CREATE_PRODUCT_MUTATION,
{variables: {data: {
photo: {
create: {
altText: `${inputs.name} featured image`,
image: {upload: inputs.image} //** HERE IS THE ERROR
},
},
name: inputs.name,
price: inputs.price,
description: inputs.description,
}}}
)
async function handleSubmit(e: any) {
e.preventDefault()
console.log(inputs);
const res = await createProduct()
console.log(res);
}
return (
<form onSubmit={e => handleSubmit(e)}>
<label htmlFor="image">
Image
<input required type="file" id="image" name="image"
onChange={handleChange}
/>
</label>
...folded
</form>
)
}
const CREATE_PRODUCT_MUTATION = gql`
mutation CreateProduct($data: ProductCreateInput!) {
createProduct(data: $data) {
name
photo {
altText
id
image {
extension
filesize
height
id
url
width
}
}
id
description
price
status
}
}
`
Error
Unhandled Runtime Error
ApolloError: Variable "$data" got invalid value {} at "data.photo.create.image.upload"; Upload value invalid.
What I tried
- https://github.com/keystonejs/keystone-discussions-archive/discussions/54#discussioncomment-120169 has a solution, but it's outdated
- i tinkered around with apollo-upload-client but I don't fully understand how to get it to play nice with Keystone.