-1

Here is my code written in TypeScript JSX:

App.js

import NavBar from './components/NavBar';
import DocketBar from './components/DocketBar';
import HeaderBar from './components/HeaderBar';
import './App.css';
import {generateData} from './data/data';
import {filterType} from './components/FilterDocket';
import {useState} from 'react';
import {Docket} from './Model/dockets';

export default function App() {
  const [filterState, setFilterState] = useState<filterType>("All dockets");
  const docketList: Docket[] = generateData();

  var docketBarList: JSX.Element[] = [];
  var docketGroup: JSX.Element[] = [];
  var groupedDockets: JSX.Element[] = [];

  function isDueToday(docket:Docket):boolean{
    if (docket.endDate !== null){
      return new Date(docket.endDate.toString()).toDateString() === new Date().toDateString();
    }
    return false;
  }

  const filterByProjects = docketList.reduce((group: { [key: string]: Array<Docket> }, docket: Docket) => {
    const {project} = docket;
    if (project !== null){
      group[project] = group[project] ?? [];
      group[project].push(docket);
    }
    return group;
  }, {});

  if (filterState === "All dockets"){
    docketBarList = docketList.map(docket => 
      <li key = {docket.docketId}>
        <DocketBar docketName = {docket.docketName} docketId = {docket.docketId} 
        statusColor = {docket.statusColor} projectSiteAddress= {docket.projectSiteAddress}/>
      </li>
    );
  }
  else if (filterState === "Due today"){
    const docketBarFiltered:Docket[] = docketList.filter(isDueToday);
    docketBarList = docketBarFiltered.map(docket => 
      <li key = {docket.docketId}>
        <DocketBar docketName = {docket.docketName} docketId = {docket.docketId} 
        statusColor = {docket.statusColor} projectSiteAddress= {docket.projectSiteAddress}/>
      </li>
    );
  }
  else{
    for (const key in Object.keys(filterByProjects)){
      docketGroup = filterByProjects[key].map(docket=>
        <li key = {docket.docketId}>
          <DocketBar docketName = {docket.docketName} docketId = {docket.docketId} 
          statusColor = {docket.statusColor} projectSiteAddress= {docket.projectSiteAddress}/>
        </li>
      );

      groupedDockets.push(
        <li key={key}>
            <div className="docketGroup">
                <div className="groupHeader">{key}</div>
                {docketGroup}
            </div>
        </li>
      );
    }
  };
  
  return (
    <>
      <NavBar/>
      <HeaderBar filterState={filterState} setFilterState={setFilterState}/>
      <div className="DocketBar">
        <ul>{filterState === "Filter by projects"? groupedDockets: docketBarList}</ul>
      </div>
    </>
  );
};

When I ran the code it gave me this error:

TypeError: Cannot read properties of undefined (reading 'map')

The error message implied that the error was most likely triggered by the line

docketGroup = filterByProjects[key].map(docket=>)

which means filterByProjects[key] was undefined. I knew that using filterByProjects[key]?.map or filterByProjects[key] && filterByProjects[key].map would resolve the error, however filterByProjects[key] was still not interpreted properly as an array of dockets after I had done so. What made it even more puzzling was that after I added the console.log() statements after the definitions of docketList and filterByProjects, their contents were both printed out properly (see the attached screenshots). console.log(docketList)

enter image description here

I would like to ask which part of my code causes filterByProjects[key] to become undefined and how to fix the code so that filterByProjects[key] is not undefined.

  • 2
    `const key in Object.keys(filterByProjects)` doesn't do what you want - `for..in` will iterate over the properties of `Object.keys(filterByProjects)` which are `0`, `1`, `2`...etc. What you want is each of the keys, so you need a `for..of` loop. https://tsplay.dev/NBBJzN – VLAZ Aug 21 '23 at 07:28

0 Answers0