How to show the last 2 elements of an array based on createdAt Code Answer

Hello Developer, Hope you guys are doing great. Today at Tutorial Guruji Official website, we are sharing the answer of How to show the last 2 elements of an array based on createdAt without wasting too much if your time.

The question is published on by Tutorial Guruji team.

I’m trying to show the 2 previous recent comments based on createdAt, by implementing this filterMethod

const filterComments = props.comments.slice(0, inc).sort((a, b) => {
    const date1 = new Date(a.createdAt) as any;
    const date2 = new Date(b.createdAt) as any;
    return date1 - date2;
});

inc is variable that increments if user selects showMore

which isn’t anything special

  const showMoreComments = () => {
        return filterComments.map((comment, i) => (
            <div key={i}>
                <CommentListContainer comment={comment} openModal={openModal} handleCloseModal={handleCloseModal} isBold={isBold} handleClickOpen={handleClickOpen} {...props} />
            </div>
        ));
    };

The problem is if the comments has more than 2 comments, the filtering gets out of order, so by default if there just 2 comments filterComments shows the recent 2 comments which works as i expect, but if there are more than 2 comments and i click on show more comments, it stops filtering correctly.

I’ve tried this method arr.slice(Math.max(arr.length - 5, 1))

In a javascript array, how do I get the last 5 elements, excluding the first element?

but its not really the answer i was looking for, i think this could be a reducer issue, or something.

What could i be doing wrong

showMoreMethod

  const showComments = (e) => {
        e.preventDefault();
        if (inc + 2 && inc <= the_comments) {
            setShowMore(inc + 2);
            setShowLessFlag(true);
        } else {
            setShowMore(the_comments);
        }
    };

CommentList.tsx

import React, { Fragment, useState } from "react";
import Grid from "@material-ui/core/Grid";
import OurSecondaryButton from "../../../common/OurSecondaryButton";
import CommentListContainer from "../commentListContainer/commentListContainer";
import storeHooks from "../../../common/storeHooks";

function CommentList(props: any) {
    const [showMore, setShowMore] = useState<Number>(2);
    const [openModal, setOpenModal] = useState(false);
    const [showLessFlag, setShowLessFlag] = useState<Boolean>(false);
    const the_comments = props.comments.length;
    const inc = showMore as any;
    const min = Math.min(2, the_comments - inc);
    const showComments = (e) => {
        e.preventDefault();
        if (inc + 2 && inc <= the_comments) {
            setShowMore(inc + 2);
            setShowLessFlag(true);
        } else {
            setShowMore(the_comments);
        }
    };
    const handleClickOpen = () => {
        setOpenModal(true);
    };
    const handleCloseModal = () => {
        setOpenModal(false);
    };

    const showLessComments = (e) => {
        e.preventDefault();
        setShowMore(2);
        setShowLessFlag(false);
    };
    const isBold = (comment) => {
        return comment.userId === props.userId ? 800 : 400;
    };

    const filterComments = props.comments.slice(0, inc).sort((a, b) => {
        const date1 = new Date(a.createdAt) as any;
        const date2 = new Date(b.createdAt) as any;
        return date1 - date2;
    });

    const showMoreComments = () => {
        return filterComments.map((comment, i) => (
            <div key={i}>
                <CommentListContainer comment={comment} openModal={openModal} handleCloseModal={handleCloseModal} isBold={isBold} handleClickOpen={handleClickOpen} {...props} />
            </div>
        ));
    };

    return (
        <Grid>
            <Fragment>
                <div style={{ margin: "30px 0px" }}>
                    {props.comments.length > 2 ? (
                        <Fragment>
                            {min !== -1 ? (
                                <Fragment>
                                    {min !== 0 ? (
                                        <OurSecondaryButton onClick={(e) => showComments(e)} component="span" color="secondary">
                                            View {min !== -1 ? min : 0} More Comments
                                        </OurSecondaryButton>
                                    ) : (
                                        <OurSecondaryButton onClick={(e) => showLessComments(e)} component="span" color="secondary">
                                            Show Less Comments
                                        </OurSecondaryButton>
                                    )}
                                </Fragment>
                            ) : (
                                <OurSecondaryButton onClick={(e) => showLessComments(e)} component="span" color="secondary">
                                    Show Less Comments
                                </OurSecondaryButton>
                            )}
                        </Fragment>
                    ) : null}
                </div>
            </Fragment>
            {showLessFlag === true ? (
                // will show most recent comments below
                showMoreComments()
            ) : (
                <Fragment>
                    {/* filter based on first comment  */}
                    {filterComments.map((comment, i) => (
                        <div key={i}>
                            <CommentListContainer comment={comment} openModal={openModal} handleCloseModal={handleCloseModal} isBold={isBold} handleClickOpen={handleClickOpen} {...props} />
                        </div>
                    ))}
                </Fragment>
            )}
        </Grid>
    );
}
// prevents un-necesary re renders
export default React.memo(CommentList);

reducer Reducer that handles the new state

 case types.COMMENT_UPDATES_SUCCESS:
    console.log(action);
    const findCommentKey2 = state.posts.findIndex((x) => x.id === action.payload.comment.postId);
    console.log(findCommentKey2);
    draft.posts[findCommentKey2].Comments = [
        action.payload.comment,
        // add comment first, then sort it out by the most recent comment
        ...draft.posts[findCommentKey2].Comments,
    ];
    return;

comment shape

[
  {
    "id": 177,
    "comment_body": "",
    "gifUrl": "https://media0.giphy.com/media/LRNxdA0soqs09YWa4F/giphy.gif?cid=e8452e68d3e94d3464efb70e1059fae80209a6b531b30b7d&rid=giphy.gif",
    "userId": 9,
    "postId": 15,
    "createdAt": "2020-05-24T21:11:07.939Z",
    "updatedAt": "2020-05-24T21:11:07.939Z",
    "author": {
      "username": "barnowl",
      "gravatar": "https://api.adorable.io/avatars/400/bf1eed82fbe37add91cb4192e4d14de6.png",
      "bio": null
    }
  },
  {
    "id": 178,
    "comment_body": "",
    "gifUrl": "https://media2.giphy.com/media/xThtalTQnCNEatzgUU/giphy.gif?cid=e8452e68d3e94d3464efb70e1059fae80209a6b531b30b7d&rid=giphy.gif",
    "userId": 9,
    "postId": 15,
    "createdAt": "2020-05-24T21:11:28.971Z",
    "updatedAt": "2020-05-24T21:11:28.971Z",
    "author": {
      "username": "barnowl",
      "gravatar": "https://api.adorable.io/avatars/400/bf1eed82fbe37add91cb4192e4d14de6.png",
      "bio": null
    }
  },
  {
    "id": 179,
    "comment_body": "fsfsfssfsf",
    "gifUrl": "",
    "userId": 9,
    "postId": 15,
    "createdAt": "2020-05-24T21:12:31.920Z",
    "updatedAt": "2020-05-24T21:12:31.920Z",
    "author": {
      "username": "barnowl",
      "gravatar": "https://api.adorable.io/avatars/400/bf1eed82fbe37add91cb4192e4d14de6.png",
      "bio": null
    }
  },
  {
    "id": 175,
    "comment_body": "fsfsfsfsfsf",
    "gifUrl": "",
    "userId": 9,
    "postId": 15,
    "createdAt": "2020-05-24T21:10:56.303Z",
    "updatedAt": "2020-05-24T21:10:56.303Z",
    "author": {
      "username": "barnowl",
      "gravatar": "https://api.adorable.io/avatars/400/bf1eed82fbe37add91cb4192e4d14de6.png",
      "bio": null
    }
  },
  {
    "id": 176,
    "comment_body": "",
    "gifUrl": "https://media3.giphy.com/media/Jrl4FlTaymFFbNiwU5/giphy.gif?cid=e8452e68f6a75bf1f94a134a15ab35ff1b0a09e2d060e1da&rid=giphy.gif",
    "userId": 9,
    "postId": 15,
    "createdAt": "2020-05-24T21:11:01.152Z",
    "updatedAt": "2020-05-24T21:11:01.152Z",
    "author": {
      "username": "barnowl",
      "gravatar": "https://api.adorable.io/avatars/400/bf1eed82fbe37add91cb4192e4d14de6.png",
      "bio": null
    }
  },
  {
    "id": 180,
    "comment_body": "fssfsffsf",
    "gifUrl": "",
    "userId": 9,
    "postId": 15,
    "createdAt": "2020-05-24T21:12:58.086Z",
    "updatedAt": "2020-05-24T21:12:58.086Z",
    "author": {
      "username": "barnowl",
      "gravatar": "https://api.adorable.io/avatars/400/bf1eed82fbe37add91cb4192e4d14de6.png",
      "bio": null
    }
  }
]

Answer

Shouldn’t you sort them first before actually slicing them?

You can first use slice(0) to clone the original array, as sort() sorts the elements locally (and you shouldn’t do that over the state).

This works for me:

const comments = [{createdAt: '2020-01-20'},{ createdAt: '2019-01-01'},{createdAt: '2019-05-01'},{createdAt: '2019-05-06'}];

const inc = 2;

const filterComments = comments.slice(0).sort((a, b) => {
    const date1 = new Date(a.createdAt);
    const date2 = new Date(b.createdAt);
    return date2 - date1;
}).slice(0, inc);

console.log(filterComments);
We are here to answer your question about How to show the last 2 elements of an array based on createdAt - If you find the proper solution, please don't forgot to share this with your team members.

Related Posts

Tutorial Guruji