Cells with Mutation

Ok, so I’ve been playing with the idea of Mutation support for cells and have been poking around a bit

Hacking a one line change (ok, 2, if you count importing useMutation) in createCell.tsx will call the useMutation instead of the useQuery (if you code a mutation into the QUERY)

export type Query = React.JSXElement
const Query = ({ children, query, ...rest }: QueryProps) => {
  const result = ('mutation' === query.definitions[0].operation) ? useQuery(query, rest) :  useMutation(query, rest)
  return result ? children(result) : null
}

I made this change in the distributed createCell.js and it called useMutation, but then it complains that the data return is null and it cannot render Success

I feel like we’re close…

Ah, the useMutation returns a completely different shape

Even executing the resulting mutation returns a different shape, a promise

I’ll have to think on this some more…

ref: [Updated] I desire mutant cells [Solved] - #13 by realStandal

I would like to collaborate with anyone on updating the cell generator to output Query and Mutation cells as needed

Cheers!

@ajoslin103 when would use a mutation cell? I am having a hard time wrapping my head around a use case. With a Cell / Query we want to fetch some data on the component mount. But when would you Mutate data on a component on mount?

I’ve updated the code from my last PR to a new one using Redwood vers 1.x

@KrisCoulson I am having a similar amount of trouble trying to figure out how to use mutations in my applications as easily as queries

When I want to do something in response to a user action I set a flag to mount components which show progress until they are done, then their completion dismounts them

// something like this 
const [ saving, setSaving ] = useState(false);
const [ dirty, setDirty ] = useState(false);
.
.
.
const handleSaveRequest = () => { setSaving(true); }
.
const handleComplete = (happyPath) => { setSaving(false); setDirty(false);   }
.
const handleError = (msg) => { setSaving(false); toastErrorMessge(msg); }
.
.
.
// when dataToBeSaved gets modified, setDirty(true) is called
.
.
.
{saving && <SavingDataCell data={dataToBeSaved} onComplete={handleComplete} onError={handleError} />}
.
{dirty && <Button title="Save" onClick={handleSaveRequest} />}
.

So the user can click to save when they have made changes… Errors are displayed and they could still attempt to save their changes again… Saving displays an indeterminate progress indicator…

yeah but you can do all of that with the useMutation hook. There’s some documentation for form errors here and you can check out the apollo useMutation documentation for all of the options you can pass to useMutation.

import { useMutation } from '@redwoodjs/web'

const [createItem, { loading, error }] = useMutation(CREATE_ITEM_MUTATION, {
    onError: () => {
      toast.error('Something went wrong. Please try again.')
    },
    onCompleted: (data) => {
      setCreatedItem(data.createItem)
    },
})

And you shouldn’t have to manage the dirty state either because you can just pull that off of the forms formstate

1 Like

I love the sound of this, it feels like the right way to do things - but it’s a bit raw and doesn’t feel Redwood to me. I can generate a cell, I’d like to be able to generate a mutation.

My sense of symmetry wants mutators to be wrapped in something - it’s like the QUERY has this great Cell wrapper and the MUTATION’s somewhere on the coffee table the morning after the party :rofl:

I listen to Syntax.fm and like how Wes talks about graphql and code generation Hasty Treat - Effortless Custom GraphQL with GraphQL Codegen — Syntax Podcast 337

I wonder if that sparks anything

we scaffold CRUD/admin & generate Cells – we need something to support mutations I think…