I am learning MERN stack with Redux and I got into the problems as I tried to print the order._id in the order page I couldn’t do it. I am not sure what is missing here that causes problems. I couldn’t print anything that is related to the current Order. Any help would be appreciated. Here is my code below;
Order.js
const mongoose = require('mongoose');
const orderSchema = mongoose.Schema(
{
user: {
type: mongoose.Schema.Types.ObjectId,
required: true,
ref: 'User',
},
orderItems: [
{
name: { type: String, required: true },
quantity: { type: Number, required: true },
image: { type: String, required: true },
price: { type: Number, required: true },
product: {
type: mongoose.Schema.Types.ObjectId,
required: true,
ref: 'Product',
},
},
],
shippingInfo: {
address: { type: String, required: true },
city: { type: String, required: true },
postalCode: { type: String, required: true },
country: { type: String, required: true },
},
paymentMethod: {
type: String,
required: true,
},
paymentResult: {
id: { type: String },
status: { type: String },
update_time: { type: String },
email_address: { type: String },
},
taxPrice: {
type: Number,
required: true,
default: 0.0,
},
shippingPrice: {
type: Number,
required: true,
default: 0.0,
},
totalPrice: {
type: Number,
required: true,
default: 0.0,
},
isPaid: {
type: Boolean,
required: true,
default: false,
},
paidAt: {
type: Date,
},
isDelivered: {
type: Boolean,
required: true,
default: false,
},
deliveredAt: {
type: Date,
},
},
{
timestamps: true,
}
)
module.exports = mongoose.model('Order', orderSchema)
OrderController.js
// Get single order => /api/order/:id
exports.getSingleOrder = catchAsyncErrors(async (req, res, next) => {
const order = await Order.findOne({_id: req.params.id}).populate('user', 'firstName email')
console.log(req.params.id)
if (!order) {
return next(new ErrorHandler('No Order found with this ID', 404))
}
res.status(200).json({
success: true,
order
})
})
**OrderActions.js**
// get ordetails for a single order by order/:id
export const getOrderDetails = (id) => async (dispatch, getState) => {
try {
dispatch({ type: GET_ORDER_REQUEST });
const { data } = await axios.get(`/api/order/${id}`)
dispatch({
type: GET_ORDER_SUCCESS,
payload: data,
})
} catch (error) {
dispatch({
type: GET_ORDER_FAIL,
payload: error.response.data.message
})
}
}
orderReducers.js
export const orderDetailsReducer = ( state = { loading: true, orderItems: [], shippingAddress: {} },action) => {
switch (action.type) {
case GET_ORDER_REQUEST:
return {
...state,
loading: true,
};
case GET_ORDER_SUCCESS:
return {
loading: false,
order: action.payload,
};
case GET_ORDER_FAIL:
return {
loading: false,
error: action.payload,
};
default:
return state;
}
};
export const orderPayReducer = (state = {}, action) => {
switch (action.type) {
case ORDER_PAY_REQUEST:
return {
loading: true,
};
case ORDER_PAY_SUCCESS:
return {
loading: false,
success: true,
};
case ORDER_PAY_FAIL:
return {
loading:false,
error: action.payload,
};
case ORDER_PAY_RESET:
return {};
default:
return state;
}
};
**Order.js**
import React, {Fragment, useEffect, useState } from 'react'
import MetaData from '../MetaData';
import { Link } from 'react-router-dom';
import { useDispatch, useSelector } from 'react-redux'
import { PayPalButton } from 'react-paypal-button-v2'
import axios from 'axios';
import { getOrderDetails, payOrder, deliverOrder } from '../actions/OrderActions';
import { ORDER_PAY_RESET } from '../constants/OrderConstants';
const Order = ({ match, history }) => {
const orderId = match.params.id
const [sdkReady, setSdkReady ] = useState(false)
const dispatch = useDispatch()
const { user } = useSelector(state => state.auth)
const orderDetails = useSelector(state => state.orderDetails)
const { order, loading, error } = orderDetails
console.log("This is order details for orderpage destructering :",order);
const orderPay = useSelector((state) => state.orderPay)
const { loading: loadingPay, success: successPay } = orderPay
const orderDeliver = useSelector((state) => state.orderDeliver)
const { loading: loadingDeliver, success: successDeliver} = orderDeliver
useEffect(() => {
if(!user) {
history.push('/login');
}
const addPayPalScript = async () => {
const { data: clientId } = await axios.get('/api/config/paypal')
const script = document.createElement('script')
script.type = 'text/javascript'
script.src = `https://www.paypal.com/sdk/js?client-id=${clientId}`
script.async = true
script.onload = () => {
setSdkReady(true)
}
document.body.appendChild(script)
}
if (!order || successPay || successDeliver || order._id !== orderId) {
dispatch({ type: ORDER_PAY_RESET })
//dispatch({ type: ORDER_DELIVER_RESET })
dispatch(getOrderDetails(orderId))
} else if (!order.isPaid) {
if (!window.paypal) {
addPayPalScript()
} else {
setSdkReady(true)
}
}
}, [dispatch, orderId, successPay, successDeliver, order])
const successPaymentHandler = (paymentResult) => {
console.log(paymentResult)
dispatch(payOrder(orderId, paymentResult))
}
const deliverHandler = () => {
dispatch(deliverOrder(order._id));
};
return (
<div className="container">
<MetaData title={'Confirm Order'} />
<div className="row d-flex justify-content-between">
<div className="col-12 col-lg-8 mt-5 order-details">
<h1 className="my-5">Order # ${order._id}</h1>
{order.user.firstName}
<h4 className="mb-4">Shipping Info</h4>
<p><b>Name:</b> {user && user.name}</p>
{/* <p><b>Phone:</b> {shippingInfo && shippingInfo.phoneNo}</p>
<p className="mb-4"><b>Address:</b>{shippingDetails}</p>
<p><b>Amount:</b> ${totalPrice}</p> */}
<hr />
<h4 className="mb-3">PAYMENT METHOD</h4>
<strong> Method:</strong>
<h4 className="mt-4">ORDER ITEMS</h4>
<Fragment>
<hr />
<div className="cart-item my-1" >
<div className="row">
<div className="col-4 col-lg-2">
<img src="" alt="Laptop" height="45" width="65" />
</div>
<div className="col-5 col-lg-6">
{/* <Link to={`/product/${item.product}`}></Link> */}
</div>
<div className="col-4 col-lg-4 mt-4 mt-lg-0">
<p></p>
</div>
</div>
</div>
<hr />
</Fragment>
</div>
<div className="col-12 col-lg-3 my-4">
<div id="order_summary">
<h4>Order Summary</h4>
<hr />
<p>Items: <span className="order-summary-values"></span></p>
<p>Shipping: <span className="order-summary-values"></span></p>
<p>Tax: <span className="order-summary-values"></span></p>
<hr />
<p>Total: <span className="order-summary-values"></span></p>
<hr />
<button id="checkout_btn" className="btn btn-primary btn-block" onClick={successPaymentHandler}>Place Order</button>
</div>
</div>
</div>
</div>
)
}
export default Order
2
Answers
Hi guys I solved this problem by doing {orderId} instead of ${order._id} thanks
Their is problem in your reducer and react component
In orderReducer.js
in your react components use
and where you want to access orderItems details like _id, name and other things
use index based orderItems like
const order_id = orderItems[0]._id
hope this this will resolve your problem