5

I want to be able to delete items of a list fetched from MongoDB.

Items of an array of the list are retrieved from MongoDB and displayed in React app (I use Typescript).

Unfortunately, I get error HERE I get error Argument of type '{ itemId: any; }' is not assignable to parameter of type 'AxiosRequestConfig'

ExpensesListItem.tsx

import React from "react";
import { IconButton, ListItem, ListItemSecondaryAction, ListItemText } from "@material-ui/core";
import DeleteIcon from '@material-ui/icons/Delete';
import { ExpenseAndAmountObject } from '../ExpenseAndAmountObject';
import axios from 'axios';
interface Props {
    expenseTitle: string;
    expenseAmount: string;
    currencySymbol: string;
    item: ExpenseAndAmountObject;
    expenseAndAmountList: Array<ExpenseAndAmountObject>;
    setExpenseAndAmountList: (value: Array<ExpenseAndAmountObject>) => void;
  }

const ExpensesListItem: React.FC<Props> = (
    {
        expenseTitle,
        expenseAmount,
        currencySymbol,
        item,
        expenseAndAmountList,
        setExpenseAndAmountList
    }: Props) => {

        const DeleteListItem = (toBeDeletedItemId: any) => {
        setExpenseAndAmountList(expenseAndAmountList.filter(el => el._id !== toBeDeletedItemId));

        axios.delete('http://localhost:4000/app/expenseslist',{itemId:toBeDeletedItemId}) 
//HERE I GET THE ERROR Argument of type '{ itemId: any; }' is not assignable to parameter of type 'AxiosRequestConfig'
        .catch(function (error) {
            console.log(error);
        });
    }
    return (
        <>
            <ListItem className="list-item">
                <ListItemText primary={expenseTitle} secondary={expenseAmount + currencySymbol} />
                <ListItemSecondaryAction>
                    <IconButton onClick={()=>DeleteListItem(item._id)} edge="end">
                        <DeleteIcon className="delete-btn" />
                    </IconButton>
                </ListItemSecondaryAction>
            </ListItem>
        </>
      );
  }
  
export default ExpensesListItem;

routes.js

 router.delete('/expenseslist', (request, response) => {
    let itemId = request.body._id;
    ExpenseAndAmountTemplate.findByIdAndRemove(itemId, function(err){
        if(err){
            response.send("/Could not delete the item...");
        } else {
            response.send("/Expenses and amount item was deleted succesfully...");
        }
     });
 });

ExpenseAndAmountModel.js (This is the model used at router.delete)

const mongoose = require('mongoose');

const ExpenseAndAmountTemplate = new mongoose.Schema({
    _id: {
        type:String,
        required:false
    },
    expenseTitle: {
        type:String,
        required:true
    },
    expenseAmount: {
        type:String,
        required:true
    }
});

module.exports = mongoose.model('ExpenseAndAmountData', ExpenseAndAmountTemplate);

Do you know how to solve it? Thanks!

rumon
  • 466
  • 2
  • 8
  • 21

2 Answers2

13

Instead of { itemId: toBeDeletedItemId } try { data: { itemId: toBeDeletedItemId } }

This way you are passing data to the request body.

Cheetha
  • 706
  • 3
  • 4
  • I've used `{ data: { itemId: toBeDeletedItemId } }` and the error is not shown anymore. However, when function DeleteListItem() is called, `Error: Request failed with status code 404` is consoled out – rumon Jun 27 '21 at 16:17
  • should `let itemId = request.params.id` or `let itemId = request.body.id` be used at `router.delete`? `Error: Request failed with status code 404`is consoled out for both – rumon Jun 27 '21 at 16:20
  • `response.redirect("/Could not delete the item...");` and `response.redirect("/Expenses and amount item was deleted succesfully...");`. For sure you want to **send** this text to the client rather than **redirect**. Assuming you are using express.js: http://expressjs.com/en/api.html#res – Cheetha Jun 27 '21 at 16:47
  • I've replaced `response.redirect` by `response.send` and I started getting `DeprecationWarning: Mongoose: `findOneAndUpdate()` and `findOneAndDelete()` without the `useFindAndModify` option set to false are deprecated.` (the items were not deleted from DB). So, I've also replaced `findByIdAndRemove` by `deleteOne`. However, now the first item in the list is deleted, it's id is ignored – rumon Jun 27 '21 at 17:13
  • It's _just_ a warning, see https://stackoverflow.com/a/52572958/16315484 for possible fixes. And the reason why the item is not deleted might be that you are accessing `request.body.id` instead of `request.body.itemId` (look at your `data: { ... }` object passed as a parameter to `axios.delete(...)`) – Cheetha Jun 27 '21 at 17:27
  • okay, I'm trying to use findOneAndDelete() again, I have updated the code in my question. – rumon Jun 27 '21 at 17:42
  • I've also added mongoose Schema that is used (maybe it is useful) – rumon Jun 27 '21 at 17:43
  • since router.delete does not delete anything from the DB, why no error message gets printed to the console? – rumon Jun 27 '21 at 17:44
  • Your schema would be 4th issue to solve in this question. I would recommend to post another question with appropriate title and provide there all the code related with this exact issue - now it's about mongodb and not about axios. – Cheetha Jun 27 '21 at 18:02
0

i would initialize an AxiosRequestConfig[1] obj, and set the data in it to what you want to pass in the request.body–then pass the config to the delete method like so:

import axios, { AxiosRequestConfig } from "axios";

const tsError = (itemId: number) => {
  axios.delete("http://localhost:4000/app/expenseslist", { itemId: itemId });
};

const tsSuccess = (itemId: number) => {
  const requestConfig: AxiosRequestConfig = {};
  requestConfig.data = { itemId: itemId };

  axios.delete("http://localhost:4000/app/expenseslist", requestConfig);
};

[1]AxiosRequestConfig: https://axios-http.com/docs/req_config