Aldor
Aldor

Reputation: 292

How to filter array from one date to another in Reactjs

I have an array of objects "mainData" like so:

0: {date: "2020-07-25T16:44:43.000Z"
description: "Qwerty"
id: 89329972},
1: {date: "2020-07-25T16:46:28.000Z"
description: "Place bins please"
id: 65586316},
2: {date: "2020-07-25T16:49:12.000Z"
description: "Solve sewerege problem"
id: 84687816},
3: {date: "2020-07-27T16:34:47.000Z"
description: "Test compl"
id: 56437370},
4: {date: "2020-07-28T08:40:34.000Z"
description: "Sewerage problem in my area"
id: 92402221},
5: {date: "2020-09-09T11:42:18.000Z"
description: "problem"
id: 25613902},

Now I am allowing the user to select from and to dates by using the mui datepicker. This is how I am receiving the values:

fromDate: Sat Jul 25 2020 11:43:00
toDate: Sat Aug 08 2020 11:43:00

Now I want to filter the array from this date to that date, including the from and to dates. I tried to do it this way but it just returns an empty array. I've put the code inside useEffect which is run every time toDate changes, Also I've used Moment to make the formats of both dates same:

 useEffect( () => {
        if (fromDate !== null && toDate !== null) {
            setReportData(
                mainData.filter(
                    (obj) =>{
                        

                        return Moment(obj.date).format("DD MMM yyyy") >= Moment(fromDate).format("DD MMM yyyy") && Moment(obj.date).format("DD MMM yyyy") <= Moment(toDate).format("DD MMM yyyy")
                    }


                )
            )

           

        }

    },[toDate])

Edit

When I select a single date :

 useEffect( () => {
        if (oneDate !== null) {

            setReportData(
                mainData.filter(
                    (obj) =>{
                   

                        return new Date(obj.date.substring(0, 19)).getTime() === oneDate.getTime()
                    }


                )
            )

        }

    },[oneDate])

Upvotes: 0

Views: 5352

Answers (2)

Apostolos
Apostolos

Reputation: 10463

Your object's date property can be parsed directly to Date object. So then you can use getTime. Also, filter returns Date object.

So, you can change your code to this

 useEffect( () => {
    if (fromDate !== null && toDate !== null) {
        setReportData(
            mainData.filter(
                (obj) =>{
                    return new Date(obj.date).getTime() >= fromDate.getTime() && new Date(obj.date).getTime() <= toDate.getTime()
                }
            )
        )
    }

},[toDate])

If you want to consider all dates to be of local timezone, then you need to remove the last part of each date's string in order for the parse method to consider each string as local timezone date.

So previous method becomes

 useEffect( () => {
    if (fromDate !== null && toDate !== null) {
        setReportData(
            mainData.filter(
                (obj) =>{
                    return new Date(obj.date.substring(0, 19)).getTime() >= fromDate.getTime() && new Date(obj.date.substring(0, 19)).getTime() <= toDate.getTime()
                }
            )
        )
    }

},[toDate])

Upvotes: 2

bron10
bron10

Reputation: 151

We can use moment.js too. By converting the moment to expected format.

In above case we have Sat Jul 25 2020 11:43:00

Moment provides locale support format using llll, which is similar to this one, usage as follow. Initialize the format constant somewhere at top, after if statement;

const format = 'llll';

And just replace the filter return statement with :

return Moment(obj.date, format).unix() >= Moment(fromDate, format).unix() && Moment(obj.date, format).unix() <= Moment(toDate, format).unix()

Upvotes: 0

Related Questions