Having trouble Updating an item with react-admin <Edit/> component

Viewed 749

Trying to get a simple edit view to update products. Right now I can successfully click the edit button on a product item in a list and the edit view renders with the product data passed into the form. However, when I edit a field and hit the save button the getOne route handler on my backend is hit while the save button stays permanently pressed with a loading symbol on it.

Meanwhile the onSuccess function for my <Edit /> throws an error in the JavaScript console saying its data prop was undefined leading me to believe nothing was returned to the component. By setting breakpoints and console.logs I'm pretty confident that the update method is being hit by the save button but I can't figure out why the update method would be hitting the getOne route handler on the backend and why it wouldn't be receiving anything back from it. The only thing I've really tried aside from basic tinkering and console logging was to give unique routes to update because the url is the same as getOne it just has a different method but it just caused more errors.

You can clone the repo or scroll down for code snippets Git clone link: https://github.com/cbddy/wholesale-portal.git

Steps to reproduce:

  1. start up the app by running npm run buil, npm run server then go to http://localhost:5000/admin#/admin-products. You must be on react-admin branch (git checkout react-admin). Also, you must rebuild and restart the server after every change.
  2. click the show button on one of the items in the list
  3. click edit in top right corner of the show comp
  4. edit one of the fields and hit save You will see the getOne route handler firing in the server and the onSuccess func throw it's error in the js console in Chrome

relevant files: frontend

  • src/components//adminSetup/dataProvider.js
  • src/components//adminSetup/Setup.js
  • src/components//adminSetup/MenuItems/Products.js backend -server/server.js -server/admin-routes/admin-product.router.js
  • React-admin version: 3.7.0
  • Last version that did not exhibit the issue (if applicable):
  • React version: 16.13.1
  • Browser: Google Chrome
  • Stack trace (in case of a JS error): ?

Here is the relevant code and errors.

edit component

export const ProductEdit = props => {
  const notify = useNotify();
  const refresh = useRefresh();
  const redirect = useRedirect();

  const onSuccess = ({ data }) => {
    notify(`Changes to product "${data.name}" saved`)
    redirect('/admin-products');
    refresh();
  };
  return (
    <Edit onSuccess={onSuccess} actions={<ProductEditActions />} title={<ProductTitle />} {...props}>
      <SimpleForm>
        {/* {!} NEEDS TO BE DONE LATER TO EDIT ORDERS OF USERS */}
        {/* <ReferenceInput source="orderId" reference="orders"> */}
        <TextInput label="Product Name" source="name" />
        <TextInput label="Category" source="category"/>
        <TextInput label="Description" source="description" options={{ multiLine: true }} />
        <NumberInput label="Price" source="price"/>
        {/* <ImageInput source="imageData"/> */}
      </SimpleForm>
    </Edit>
  )
}

DataProvider methods for getOne and update

  getOne: (resource, params) => {
    console.log("getOne resource", resource);
    return httpClient(`${apiUrl}/${resource}/${params.id}`)
    .then(({ json }) => {
      console.log(json);
      return { data: json };
    })
  },

  update: (resource, params) => {
    console.log("update", resource);
    return httpClient(`${apiUrl}/${resource}/${params.id}`, {
      method: "PUT",
      body: JSON.stringify(params.data),
    }).then(({ json }) => {
      return { data: json }
    }).catch(err => {
      return displayErrorMessage(err)
    })
  },

backend route handlers for getOne and update

//getOne
router.get("/:id", async (req, res) => {
  console.log("req method :", req.method)
  console.log("req.data :", req.data)
  console.log("getOne hit. Id: ", req.params.id)
  await Product.findOne({_id: req.params.id})
  .then(async (product) => {
    product = await JSON.parse(JSON.stringify(product).split('"_id":').join('"id":'));
    console.log("parsed product: ", product)
    res.json(product)
  }).catch(err => {
    console.log("error: ", err)
    res.status(500).send("user not found.")
  })
})

router.put("/:id", async (req, res) => {
  console.log("update hit")
  console.log("id: ", req.params.id)
  console.log("body: ", req.body)
  await Product.updateOne({_id: req.params.id}, req.body)
  .then(async (product) => {
    product.save();
    product = await JSON.parse(JSON.stringify(product).split('"_id":').join('"id":'));
    return res.status(200).json(product)
  }).catch(err => {
    console.log(err)
    res.status(500).send("Failed to update.")
  })
})

My browser directly after hitting save

0 Answers
Related