title: React, Graphql - useMutation to delete from DB
body: <p>I'm trying tok create a simple demo CRUD app using React and Graphql</p>
  
  <p>I have the backend all set and working.</p>
  
  <p>On the front end I'm using React with useQuery and useMutation.</p>
  
  <p>I have the create working with useMutation to create the data and the read with useQuery to show the data.</p>
  
  <p>I now stuck with the delete. I have a button the post and I can get the id of the post to pass to the useMutation function to delete the post.</p>
  
  <p>I'm just stuck getting it to work if anyon can help.</p>
  
  <p>App.tsx</p>
  
  <pre><code>import React, { useState } from 'react';
  import './App.css';
  
  import { RecipeData } from '../generated/RecipeData';
  import { GET_ALL_RECIPES, ADD_RECIPE, DELETE_RECIPE } from '../queries';
  import { useQuery, useMutation } from 'react-apollo-hooks';
  
  
  const App: React.FC = () =&gt; {
  
    const [name, setName] = useState&lt;string&gt;('')
    const [description, setDes] = useState&lt;string&gt;('')
    const [id, setId] = useState&lt;string&gt;('')
  
    const handleNameChange = (e: React.ChangeEvent&lt;HTMLInputElement&gt;) =&gt; {
      setName(e.target.value)
    }
  
    const handleDesChange = (e: React.ChangeEvent&lt;HTMLInputElement&gt;) =&gt; {
      setDes(e.target.value)
    }
  
    const handleClick = (e: React.MouseEvent&lt;HTMLButtonElement&gt;) =&gt; {
      e.preventDefault()
      createRecipe()
    };
  
    const handelDelete = (e: React.MouseEvent&lt;HTMLButtonElement&gt;) =&gt; {
      setId(e.target.parentElement.getAttribute("data-id"))
      deleteRecipe()
    }
  
    const [deleteRecipe] = useMutation(DELETE_RECIPE, {
      variables: { id }, refetchQueries: ['RecipeData']
    })
  
    const [createRecipe, { error }] = useMutation(ADD_RECIPE, {
      variables: { name, description }, refetchQueries: ['RecipeData']
    })
    if (error) {
      console.error('erroring : ', error)
    }
  
    const { data, loading } = useQuery&lt;RecipeData | null&gt;(GET_ALL_RECIPES, {
      suspend: false
    })
  
    if (loading || !data) return &lt;div&gt;Loading&lt;/div&gt;
  
    return (
      &lt;div className="App"&gt;
        &lt;h1&gt;Graphql&lt;/h1&gt;
        &lt;ul&gt;
          {
            data.recipe !== null &amp;&amp; data.recipe.map((recipe, i) =&gt; (
              &lt;li key={recipe._id} data-id={recipe._id}&gt;
                {recipe.name}
                &lt;button onClick={handelDelete}&gt;X&lt;/button&gt;
              &lt;/li&gt;
            ))
          }
        &lt;/ul&gt;
  
        &lt;form&gt;
          &lt;div&gt;
            &lt;label&gt;Name&lt;/label&gt;
            &lt;input
              type="text"
              value={name}
              onChange={handleNameChange}
            /&gt;
          &lt;/div&gt;
          &lt;div&gt;
            &lt;label&gt;Description&lt;/label&gt;
            &lt;input
              type="text"
              value={description}
              onChange={handleDesChange}
            /&gt;
          &lt;/div&gt;
          &lt;button onClick={handleClick}&gt;Add Recipe&lt;/button&gt;
        &lt;/form&gt;
      &lt;/div&gt;
    );
  }
  
  export default App;
  </code></pre>
  
  <p>queries/index.tsx</p>
  
  <pre><code>import { gql } from 'apollo-boost';
  
  export const GET_ALL_RECIPES = gql`
    query RecipeData{
      recipe{
        _id
        name
        description
      }
    }
  `
  export const ADD_RECIPE = gql`
    mutation addRecipe($name: String!, $description:String){
      addRecipe(name: $name, description: $description){
        _id
        name
        description
      }
    }
  `
  
  export const DELETE_RECIPE = gql`
    mutation deleteRecipe($id: Int!){
      deleteRecipe(_id: $id){
        _id
        name
        description
      }
    }
  `   
  </code></pre>
  
  <p>Server side</p>
  
  <p>schema.js</p>
  
  <pre><code>exports.typeDefs = `
  
    type Recipe{
      _id: ID
      name: String
      description: String
    }
  
    type Query{
      recipe:[Recipe]
    }
  
    type Mutation{
      addRecipe(name: String!, description: String):Recipe
      deleteRecipe(_id: Int):Recipe
    }
  
  `   
  </code></pre>
  
  <p>resolvers.js</p>
  
  <pre><code>exports.resolvers = {
  
    Query:{
      recipe: async(obj, args, {Recipe}, info) =&gt; {
        const allRecipes = await Recipe.find()
        return allRecipes
      }
    },
    Mutation:{
      addRecipe: async(obj, {name, description}, {Recipe}, info) =&gt; {
        const newRecipe = await new Recipe({
          name,
          description
        }).save()
        return newRecipe
      },
      deleteRecipe: async(obj, args, {Recipe}, info, {_id}) =&gt; {
        delete Recipe[_id];
      }
    }
  
  }   
  </code></pre>
  
  <p>I don't have a live demo sorry but this outputs a list of recipe name with an input field to add new recipes, this part works.</p>
  
  <p>I also have a delete button after each recipe displayed. I wanted to click this button and have that recipe be removed from the list.</p>
  
  <p>At the moment when I click this delete button I get the following error message in the network tab of the dev tools</p>
  
  <p><code>message: "Variable "$id" got invalid value ""; Expected type Int. Int cannot represent non-integer value: """
  </code></p>