how to delete a user from the client side mern stack?

Viewed 356

hi eveyone i am having issue to delete a user from client side app and also delete the user from the data base, i want the client side to delete a user from the data base, i have checked my api on the server side and in postman i am deleting the user successfully, when i try to make the same request from the client side im not deleting instead when i make the request with the id to delete the user im getting back id undefined, this is a mern stack app which i am making, any help would be much appreciated

  1. controller

export const deleteOneUser = async (req, res, next) => {
  const { id } = req.body;
  try {
    const user = await UserModal.findByIdAndRemove(req.params.id);

    return res.status(200).json({
      oneUserDeleted: true,
      data: user,
    });
  } catch (error) {
    return res.status(500).json({
      sucess: false,
      cannotDeleteUser: "Server Error",
    });
  }
};

export const getOneUser = async (req, res, next) => {
  try {
    const user = await UserModal.findById(req.params.id);

    if (!user) {
      return res.status(404).json({
        success: false,
        error: "No user found",
      });
    }

    return res.status(200).json({
      oneUserFound: true,
      data: user,
    });
  } catch (error) {
    return res.status(500).json({
      sucess: false,
      error: "Server Error",
    });
  }
};

  1. user Routes

import express from "express";
const router = express.Router();
import auth from "../middleware/auth.js";

import {
  getOneUser,
  deleteOneUser,
 } from "../controllers/user.js";

router.delete("/userId/:id", deleteOneUser);

router.get("/userId/:id", getOneUser);

export default router;

  1. index.js

import express from "express";
import mongoose from "mongoose";
import cors from "cors";
import colors from "colors";
import morgan from "morgan";

import userRouter from "./routes/user.js";
import transactionsRouter from "./routes/transactions.js";

const app = express();

app.use(express.json({ limit: "30mb", extended: true }));
app.use(express.urlencoded({ limit: "30mb", extended: true }));
app.use(cors());
app.use(morgan("dev"));

app.use("/user", userRouter);
app.use("/login/account/transactions", transactionsRouter);

const CONNECTION_URL =
  "CONNECTED TO MONGO DB CLUSTER";
const PORT = process.env.PORT || 5000;

mongoose
  .connect(CONNECTION_URL, {
    useNewUrlParser: true,
    useUnifiedTopology: true,
  })
  .then(() =>
    app.listen(PORT, () =>
      console.log(`Server running on port ${PORT}`.cyan.bold)
    )
  )
  .catch((error) => console.log(error.message));

mongoose.set("useFindAndModify", false);

  1. Client Side React.js --> GLOBAL STATE

import React, { createContext, useReducer } from "react";
import AppReducer from "./AppReducer";
import axios from "axios";

// Initial state
const initialState = {
  transactions: [],
  accounts: [],
  error: null,
  loading: true,
  user: [],
};

// Create context
export const GlobalContext = createContext(initialState);
console.log(initialState);

// Provider Component
export const GlobalProvider = ({ children }) => {
  const [state, dispatch] = useReducer(AppReducer, initialState);

  // Actions
  async function getTransactions() {
    try {
      const res = await axios.get("/login/account/transactions");

      dispatch({
        type: "GET_TRANSACTIONS",
        payload: res.data.data,
      });
    } catch (error) {
      dispatch({
        type: "TRANSACTIONS_ERROR",
        payload: error.response.data.error,
      });
    }
  }


  async function deleteUser(id, user) {
    try {
      await axios.delete(`/user/userId/${id}`, user);

      dispatch({
        type: "DELETE_ONE_USER",
        payload: id,
      });
    } catch (error) {
      dispatch({
        type: "TRANSACTIONS_ERROR",
        payload: error.response.data.error,
      });
    }
  }

  async function addTransaction(transaction, amount) {
    const config = {
      headers: {
        "Content-Type": "application/json",
      },
    };

    try {
      const res = await axios.post(
        "/login/account/transactions",
        transaction,
        config
      );

      dispatch({
        type: "ADD_TRANSACTION",
        payload: res.data.data,
        amount: +amount,
      });
    } catch (error) {
      dispatch({
        type: "TRANSACTION_ERROR",
        payload: error.response.data.error,
      });
    }
  }

  async function deleteTransaction(transaction, amount) {
    const config = {
      headers: {
        "Content-Type": "application/json",
      },
    };

    try {
      const res = await axios.post(
        "/login/account/transactions",
        transaction,
        config
      );

      dispatch({
        type: "DELETE_TRANSACTION",
        payload: res.data.data,
        amount: -amount,
      });
    } catch (error) {
      dispatch({
        type: "TRANSACTION_ERROR",
        payload: error.response.data.error,
      });
    }
  }



  return (
    <GlobalContext.Provider
      value={{
        transactions: state.transactions,
        user: state.user,
        error: state.error,
        loading: state.loading,
        deleteTransaction,
        addTransaction,
        getTransactions,
        deleteUser,
      }}
    >
      {children}
    </GlobalContext.Provider>
  );
};

  1. AppReducer

/* eslint-disable import/no-anonymous-default-export */

export default (state, action) => {
  switch (action.type) {
    case "GET_TRANSACTIONS":
      return {
        ...state,
        loading: false,
        transactions: action.payload,
      };
    case "DELETE_ONE_USER":
      return {
        ...state,
        loading: false,
        user: state.users.filter((user) => user._id === action.payload),
      };
    case "ADD_TRANSACTION":
      return {
        ...state,
        transactions: [...state.transactions, action.payload],
      };
    case "DELETE_TRANSACTION":
      return {
        ...state,
        transactions: [...state.transactions, action.payload],
      };
    case "TRANSACTION_ERROR":
      return {
        ...state,
        error: action.payload,
      };
    default:
      return state;
  }
};

  1. Account Transactions --> THIS IS WHERE IM TRYING TO EXECUTE THE CODE TO DELETE USER

import React, { useState, useContext, useEffect } from "react";
import { GlobalContext } from "../../context/GlobalState";

import { ToastContainer, toast } from "react-toastify";
import "react-toastify/dist/ReactToastify.css";

const AccountTransactions = () => {
  const {
    deleteTransaction,
    addTransaction,
    user: userId,
    deleteUser,
  } = useContext(GlobalContext);


  const [amount, setAmount] = useState("");
  const [depositMoney, setDepositMoney] = useState({ DepositMoney: "" });
  const [withdrawMoney, setWithdrawMoney] = useState({ WithdrawMoney: "" });
  const [user, setUser] = useState({
    name: "",
    password: "",
    firstName: "",
    lastName: "",
    email: "",
  });


  const onSubmitUser = (e) => {
    e.preventDefault(e);
    deleteUser(userId);

    setUser({ ...user, [e.target.name]: e.target.value });
    e.target.reset(user);
  };

  const onSubmit = (e) => {
    e.preventDefault(e);
    notifyDeposit();

    const newTransaction = {
      amount: +amount,
    };

    setDepositMoney({ ...depositMoney, [e.target.name]: e.target.value });
    addTransaction(newTransaction);
    e.target.reset(depositMoney);
  };

  const onSubmitWithdraw = (e) => {
    e.preventDefault(e);
    notifyWithdrawal();

    const Transaction = {
      amount: -amount,
    };

    setWithdrawMoney({ ...withdrawMoney, [e.target.name]: e.target.value });
    deleteTransaction(Transaction);
    e.target.reset(withdrawMoney);
  };

  const notifyDeposit = () =>
    toast.success("Successfully Deposited!", {
      className: "custom Toast",
      draggable: true,
      position: toast.POSITION.TOP_CENTER,
    });

  const notifyWithdrawal = () =>
    toast.warn("successfull withdraw!", {
      className: "custom Toast",
      draggable: true,
      position: toast.POSITION.TOP_CENTER,
    });

  return (
    <div className="pb-52 pt-10">
      <div className="flex-1 max-w-5xl mx-auto text-center shadow-md">
        <div className="grid grid-cols-3 grid-rows-1 grid-flow-row gap-6 bg-white rounded-lg shadow-lg pt-3 px-2">
          <form onSubmit={onSubmit}>
            <h5 className="col-span-1 rounded-lg shadow-xl border-2 border-blue-400 bg-blue-300">
              Deposit Money
              <div className="gap-2 py-2 px-1">
                <div className="flex justify-center m-2 gap-2">
                  <input
                    className="relative border-2 placeholder-gray-300 text-gray-700 bg-white rounded-md w-full h-10 text-sm text-center outline-none"
                    name="DepositMoney"
                    placeholder="Enter amount..."
                    required
                    type="number"
                    value={depositMoney.amount}
                    onChange={(e) => setAmount(e.target.value)}
                  />

                  <button
                    type="submit"
                    className="bg-blue-400 px-1 rounded-lg"
                  >
                    {<ToastContainer />}
                    <svg
                      xmlns="http://www.w3.org/2000/svg"
                      className="h-10 w-5 text-white"
                      viewBox="0 0 20 20"
                      fill="currentColor"
                    >
                      <path
                        fillRule="evenodd"
                        d="M10.293 3.293a1 1 0 011.414 0l6 6a1 1 0 010 1.414l-6 6a1 1 0 01-1.414-1.414L14.586 11H3a1 1 0 110-2h11.586l-4.293-4.293a1 1 0 010-1.414z"
                        clipRule="evenodd"
                      />
                    </svg>
                  </button>
                </div>
              </div>
            </h5>
          </form>

          <form onSubmit={onSubmitWithdraw}>
            <h5 className="col-span-1 rounded-lg shadow-xl border-2 border-green-400 bg-green-300">
              Withdraw Money
              <div className="gap-2 py-2 px-1">
                <div className="flex justify-center m-2 gap-2">
                  <input
                    className="relative border-2 placeholder-gray-300 text-gray-700 bg-white rounded-md w-full h-10 text-sm text-center outline-none"
                    name="WithdrawMoney"
                    placeholder="Enter amount..."
                    required
                    type="number"
                    value={withdrawMoney.amount}
                    onChange={(e) => setAmount(e.target.value)}
                  />
                  <button
                    type="submit"
                    className="bg-green-400 px-1 rounded-lg"
                  >
                    {<ToastContainer />}
                    <svg
                      xmlns="http://www.w3.org/2000/svg"
                      className="h-10 w-5 text-white"
                      viewBox="0 0 20 20"
                      fill="currentColor"
                    >
                      <path
                        fillRule="evenodd"
                        d="M10.293 3.293a1 1 0 011.414 0l6 6a1 1 0 010 1.414l-6 6a1 1 0 01-1.414-1.414L14.586 11H3a1 1 0 110-2h11.586l-4.293-4.293a1 1 0 010-1.414z"
                        clipRule="evenodd"
                      />
                    </svg>
                  </button>
                </div>
              </div>
            </h5>
          </form>

          <h5 className="col-span-1 rounded-lg shadow-xl border-2 border-red-500 bg-red-300">
            Close Account
            <form onSubmit={onSubmitUser}>
              <div className="flex justify-center gap-2 py-2 px-1">
                <div className="flex justify-center m-2 gap-2">
                  <input
                    className="relative border-2 placeholder-gray-300 text-gray-700 bg-white rounded-md w-32 h-10 text-sm text-center outline-none"
                    type="name"
                    name="name"
                    placeholder="User Name"
                    required
                    value={user.name}
                    onChange={(e) => setUser(e.target.value)}
                  />

                  <input
                    className="relative border-2 placeholder-gray-300 text-gray-700 bg-white rounded-md w-32 test text-sm text-center outline-none"
                    type="name"
                    placeholder="First Name"
                    name="firstName"
                    required
                    onChange={(e) => setUser(e.target.value)}
                    value={user.lastName}
                  />
                  <input
                    className="relative border-2 placeholder-gray-300 text-gray-700 bg-white rounded-md w-32 test text-sm text-center outline-none"
                    type="name"
                    placeholder="Last Name"
                    name="lastName"
                    required
                    onChange={(e) => setUser(e.target.value)}
                    value={user.firstName}
                  />
                  <input
                    className="relative border-2 placeholder-gray-300 text-gray-700 bg-white rounded-md w-32 test text-sm text-center outline-none"
                    type="email"
                    placeholder="Email"
                    name="email"
                    required
                    onChange={(e) => setUser(e.target.value)}
                    value={user.email}
                  />

                  <input
                    className="relative border-2 placeholder-gray-300 text-gray-700 bg-white rounded-md w-32 test text-sm text-center outline-none"
                    type="password"
                    placeholder="Password"
                    name="password"
                    required
                    onChange={(e) => setUser(e.target.value)}
                    value={user.password}
                  />
                  <button
                    onClick={() => deleteUser(user._id)}
                    className="bg-red-400 px-1 rounded-lg"
                    type="submit"
                  >
                    <svg
                      xmlns="http://www.w3.org/2000/svg"
                      className="h-10 w-5 text-white"
                      viewBox="0 0 20 20"
                      fill="currentColor"
                    >
                      <path
                        fillRule="evenodd"
                        d="M10.293 3.293a1 1 0 011.414 0l6 6a1 1 0 010 1.414l-6 6a1 1 0 01-1.414-1.414L14.586 11H3a1 1 0 110-2h11.586l-4.293-4.293a1 1 0 010-1.414z"
                        clipRule="evenodd"
                      />
                    </svg>
                  </button>
                </div>
              </div>
            </form>
          </h5>
        </div>
      </div>
    </div>
  );
};

export default AccountTransactions;

0 Answers
Related