I'm trying to get a list of orders to be shown in chronological order, but I can't get this to work. My data is stored in a Mongodb database, and I'm using react.js for my frontend. I have tried using a sort:
{orders.sort((a,b) => b.createdAt - a.createdAt).map((order) => (....)}
but nothing is changing. I would really appreciate any help or advice on how I can fix this. Thank you!
Full code for this page:
import React, { useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { deleteOrder, listOrders } from '../actions/orderActions';
import LoadingBox from '../components/LoadingBox';
import MessageBox from '../components/MessageBox';
import { ORDER_DELETE_RESET } from '../constants/orderConstants';
export default function OrderListScreen(props) {
const orderList = useSelector((state) => state.orderList);
const { loading, error, orders } = orderList;
const orderDelete = useSelector((state) => state.orderDelete);
const {
loading: loadingDelete,
error: errorDelete,
success: successDelete,
} = orderDelete;
const userSignin = useSelector((state) => state.userSignin);
const { userInfo } = userSignin;
const dispatch = useDispatch();
useEffect(() => {
dispatch({ type: ORDER_DELETE_RESET });
dispatch(listOrders({ seller: sellerMode ? userInfo._id : '' }));
}, [dispatch, sellerMode, successDelete, userInfo._id]);
const deleteHandler = (order) => {
// TODO: delete handler
if (window.confirm('Are you sure to delete?')) {
dispatch(deleteOrder(order._id));
}
};
return (
<div>
<h1>Orders</h1>
{loadingDelete && <LoadingBox></LoadingBox>}
{errorDelete && <MessageBox variant="danger">{errorDelete}</MessageBox>}
{loading ? (
<LoadingBox></LoadingBox>
) : error ? (
<MessageBox variant="danger">{error}</MessageBox>
) : (
<table className="table">
<thead>
<tr className="table_row">
<th className="main">ID</th>
<th className="main">DATE</th>
<th className="main">TOTAL</th>
<th className="main">ACTIONS</th>
</tr>
</thead>
<tbody>
{orders.sort((a,b) => b.createdAt - a.createdAt).map((order) => (
<tr className="table_row" key={order._id}>
<td className="data">{order._id}</td>
<td className="data">{order.createdAt.substring(0, 10)}</td>
<td className="data">{order.totalPrice.toFixed(2)}</td>
<td className="data">
<button
type="button"
className="small"
onClick={() => {
props.history.push(`/order/${order._id}`);
}}
>
Details
</button>
<button
type="button"
className="small"
onClick={() => deleteHandler(order)}
>
Delete
</button>
</td>
</tr>
))}
</tbody>
</table>
)}
</div>
);
}
CodePudding user response:
If it is an ISO-8601 string you can use the Date
constructor which will parse the string to a date which you can then substract.
// ISO string creates a ISO-8601 string
const dates = [new Date(2022, 4, 26).toISOString(), new Date(2022, 4, 23).toISOString(), new Date(2022, 3, 23).toISOString(), new Date(2022, 5, 23).toISOString(), new Date(2021, 4, 23).toISOString()];
console.log(dates);
dates.sort((a, b) => new Date(a) - new Date(b));
console.log(dates);
If you want to actually have Date
objects to work with you can use map()
before which will return an array of Date
objects which you can work with.
// ISO string creates a ISO-8601 string
const dates = [new Date(2022, 4, 26).toISOString(), new Date(2022, 4, 23).toISOString(), new Date(2022, 3, 23).toISOString(), new Date(2022, 5, 23).toISOString(), new Date(2021, 4, 23).toISOString()];
console.log(dates);
const sortedParsedDates = dates.map(dateStr => new Date(dateStr)).sort((a, b) => a - b);
console.log(sortedParsedDates);
// now we actually have Date objects we can work with
console.log(sortedParsedDates[0] instanceof Date);