skip to Main Content

I know this is a very popular problem, but here goes. So I have an array of records coming in and need to filter them. I am filtering them by date, and I need them to be <=7 and >=1 days from today()s date.

const Today = new Date();
    const thirtyday = Today - 30;
    const sevenday = Today - 7;
    const oneday = Today - 1;
    const machinerecords = this.state.tasksnfiltered;


const due = machinerecords.filter(
      (record) =>
        Date.parse(record.nextdue) <= sevenday &&
        Date.parse(record.nextdue) >= oneday
    );

    {
      this.setState({ due: [...due] });
    }

I have also tried

machinerecords
      .filter((record) => Date.parse(record.nextdue) <= thirtyday)
      .filter((record) => Date.parse(record.nextdue) >= sevenday);

The info is coming from a backend I built.

I can get the first filter to run alone accurately for any of the date filters. but cant combine them.

2

Answers


  1. In JavaScript dates have a millisecond representation so your code above is testing for dates between 7 and 1 milliseconds from today so depending on how your reference dates are generated something like the following may work as long as the h/m/s part of your dates are ignorable.

    const Today = new Date.now(); // timestamp in milliseconds
        const thirtyday = Today - 30 * 24 * 3600000;
        const sevenday = Today - 7 * 24 * 3600000;
        const oneday = Today - 1 * 24 * 3600000;
        const machinerecords = this.state.tasksnfiltered;
    
    
    const due = machinerecords.filter(
          (record) =>
            Date.parse(record.nextdue.getTime()) <= sevenday &&
            Date.parse(record.nextdue.getTime()) >= oneday
        );
    

    For react though I generally use the date-fns library https://date-fns.org/docs/Getting-Started as its really lightweight compared to momentjs.

    date-fns handles ignoring h/m/s issues as well as ‘enough’ timezone handling to be useful.

    Login or Signup to reply.
  2. Most of the filtering logic can exist outside of the component.

    Below, I spawned a couple tasks with dates ranging from half a day to ten days.

    Only the tasks with a due date within two and five days should be displayed. This can be achieved by comparing two date objects. I assume your nextdue date is serialized into a timestamp e.g. YYYY-MM-DD.

    const filterTasks = (tasks, afterDate, beforeDate) =>
      tasks.filter((task) => {
        const dueDate = Date.parse(task.nextdue);
        return dueDate >= afterDate && dueDate <= beforeDate;
      });
    

    Here is a working React (function component) snippet.

    const { useEffect, useMemo, useState, StrictMode } = React;
    
    const DAY_IN_MILLIS = 8.64e7;
    
    const addMillis = (date, millis) => new Date(date.getTime() + millis)
    
    // Sweedish dates are in the format YYYY-MM-DD
    const tsFrom = (date, millis) => addMillis(date, millis).toLocaleDateString('sv-SE');
    
    const now      = new Date();
    const halfDay  = tsFrom(now, Math.floor(DAY_IN_MILLIS / 2));
    const twoDays  = tsFrom(now, DAY_IN_MILLIS * 2);
    const fiveDays = tsFrom(now, DAY_IN_MILLIS * 5);
    const tenDays  = tsFrom(now, DAY_IN_MILLIS * 10);
    
    const fetchTasks = () => Promise.resolve([
      { id: 1, nextdue: halfDay,  label: 'Half Day'  },
      { id: 2, nextdue: twoDays,  label: 'Two Days'  },
      { id: 3, nextdue: fiveDays, label: 'Five Days' },
      { id: 4, nextdue: tenDays,  label: 'Ten Days'  }
    ]);
    
    const filterTasks = (tasks, afterDate, beforeDate) =>
      tasks.filter((task) => {
        const dueDate = Date.parse(task.nextdue);
        return dueDate >= afterDate && dueDate <= beforeDate;
      });
    
    const TaskApp = () => {
      const [tasks, setTasks] = useState([]);
      
      useEffect(() => {
        fetchTasks().then(setTasks);
      }, []);
      
      const filteredTasks = useMemo(() => {
        const now = new Date();
        const oneDay = addMillis(now, DAY_IN_MILLIS * 1);
        const oneWeek = addMillis(now, DAY_IN_MILLIS * 7);
        return filterTasks(tasks, oneDay, oneWeek);
      }, [tasks]);
      
      return (
        <ul>
          {filteredTasks.map((task) => (
            <li key={task.id}>{task.label}</li>
          ))}
        </ul>
      );
    };
    
    ReactDOM.createRoot(document.getElementById("root")).render(
      <StrictMode>
        <TaskApp />
      </StrictMode>
    );
    <div id="root"></div>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.development.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.development.js"></script>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search