How do i get signed in users information in with reactjs and mongodb?

Viewed 35

I have a MERN system that manages customers' orders. I hope on the /orders page, I can show orders of the authenticated/logged user.

The controller of fetching orders I designed was like:

const mongoose = require('mongoose');

const HttpError = require('../models/http-error');
const Order = require('../models/order');
const User = require('../models/user');

const getOrderbyId = async (req, res, next) => {
  const orderId = req.params.oid;

  let order;
  try {
    order = await Order.findById(orderId);
  } catch (err) {
      const error = new HttpError(
        'Something went wrong, could not find the order.',
        500
      );
    return next(error);
  }
  
  if (!order) {
    const error = new HttpError(
      'Could not find order for the provided id.',
      404
    );
    return next(error);
  }
  
  res.json({ order: order.toObject({ getters: true }) });
}

const getOrdersbyUserId = async (req, res, next) => {
  const userId = req.params.uid;

  let userWithOrders;
    try {
      userWithOrders = await User.findById(userId).populate('orders');
    } catch (err) {
      const error = new HttpError(
        'Fetching orders failed, please try again later.',
        500
      );
      return next(error);
    }
  
    // if (!places || places.length === 0) {
    if (!userWithOrders || userWithOrders.places.length === 0) {
      return next(
        new HttpError('Could not find orders for the provided user id.', 404)
      );
    }
  
    res.json({ orders: userWithOrders.orders.map(order => order.toObject({ getters: true })) });
}
...

The routes I assigned for it was:

router.get('/:oid', ordersControllers.getOrderbyId);

router.get('/user/:uid', ordersControllers.getOrdersbyUserId);

In App.js of the backend I did it like:

app.use('/api/orders', ordersRoutes);

In the frontend, I wish to grab the user's order, I am pretty sure there has context in the database:

import React, { useEffect, useState } from 'react';
import { useParams } from 'react-router-dom';

import OrderList from '../components/OrderList';
import ErrorModal from '../../shared/components/UIElements/ErrorModal';
import LoadingSpinner from '../../shared/components/UIElements/LoadingSpinner';
import { useHttpClient } from '../../shared/hooks/http-hook';

const Uorders = () => {
  const [ loadedOrders, setLoadedOrders ] = useState();
  const { isLoading, error, sendRequest, clearError } = useHttpClient();

  const userId = useParams().userId;

  useEffect(() => {
    const fetchOrders = async () => {
      try {
        const responseData = await sendRequest(
          `http://localhost:5000/api/orders/user/${userId}`
        );
        setLoadedOrders(responseData.orders);
      } catch (err) {}
    };
    fetchOrders();
  }, [sendRequest, userId]);

  console.log(userId);
  console.log(loadedOrders);

  return (
    <React.Fragment>
      <ErrorModal error={error} onClear={clearError} />
      {isLoading && (
        <div className="center">
          <LoadingSpinner />
        </div>
      )}
      {!isLoading && loadedOrders && <OrderList items={loadedOrders} />}
    </React.Fragment>
  );
};

export default Uorders;

However, it gives me 500 error. I am confused about which mistake I made in the backend or frontend? It there any correct or improvement I can try?

1 Answers

Try to add an exec() call after populate() on the getOrdersbyUserId function:

const getOrdersbyUserId = async (req, res, next) => {
  const userId = req.params.uid;

  try {
    const userWithOrders = await User.findById(userId)
      .populate('orders')
      .exec();

    if (!userWithOrders || userWithOrders.places.length === 0) {
      return next(
        new HttpError('Could not find orders for the provided user id.', 404)
      );
    }

    return res.json({
      orders: userWithOrders.orders.map((order) =>
        order.toObject({ getters: true })
      ),
    });
  } catch (err) {
    const error = new HttpError(
      'Fetching orders failed, please try again later.',
      500
    );
    return next(error);
  }
};
Related