Reputation: 191
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>
);
}
Upvotes: 0
Views: 53
Reputation: 9168
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. This is quite useful if you want to do some further processing with the dates.
// 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);
Upvotes: 2