Home > database >  **Uncaught TypeError: Cannot read properties of undefined (reading 'map')**
**Uncaught TypeError: Cannot read properties of undefined (reading 'map')**

Time:10-16

Im new in reactjs am stuck with this error I all try what I can do to resolved it but I could'nt The error is on line 38 wheere the map is. My data collection is inside th app.jsx. when I run it, it's showing me blank on the screen. Thanks I realy appriacite for your help

This is my GroupedTeamMember.jsx

import { useState } from "react";

const GroupedTeamMembers = ({employees, selectedTeam, setTeam}) => {

    const [groupedEmployees, setGroupedData] = useState(groupTeamMembers);

    function groupTeamMembers() {
        var teams = [];

        var teamAMembers = employees.filter((employee) => employee.teamName === 'TeamA');
        var teamA = { team: 'TeamA', members: teamAMembers, collapsed: selectedTeam === 'TeamA'?false:true}
        teams.push(teamA);

        var teamBMembers = employees.filter((employee) => employee.teamName === 'TeamB');
        var teamB = { team: 'TeamB', members: teamBMembers, collapsed: selectedTeam === 'TeamB'?false:true}
        teams.push(teamB);

        var teamCMembers = employees.filter((employee) => employee.teamName === 'TeamC');
        var teamC = { team: 'TeamC', members: teamCMembers, collapsed: selectedTeam === 'TeamC'?false:true}
        teams.push(teamC);

        var teamDMembers = employees.filter((employee) => employee.teamName === 'TeamD');
        var teamD = { team: 'TeamD', members: teamDMembers, collapsed: selectedTeam === 'TeamD'?false:true}
        teams.push(teamD);
    }   

    function handleTeamClick(event) {
        var transformedGroupData = groupedEmployees.map((groupedData) => groupedData.team === event.currentTarget.id 
            ?{...groupedData, collapsed:!groupedData}
            :groupedData);

        setGroupedData(transformedGroupData);
        setTeam(event.currentTarget.id);
    }

    return (
        <main className="container">
           {
            groupedEmployees.map((item) => {
                return (
                    <div key ={item.team} className='card mt2' style={{cursor:"pointer"}} onClick={handleTeamClick}>
                        <h4 id={item.team} className="card-header text-secondary bg-white">
                            Team Name: {item.team}
                        </h4>
                        <div id={"collapse_"   item.team}
                            className={item.collapsed === true?"collap": ""}>
                            <hr />
                            {
                                item.members.map(member => {
                                    return (
                                        <div className="mt-2">
                                            <h5 className="card-title mt-2">
                                                <span className="text-dark">Full Name: {member.fullName}</span>
                                            </h5>
                                            <p>Designation: {member.designation}</p>
                                        </div>
                                    )
                                })
                            }
                        </div>
                    </div>
                )
            }) 
           }
        </main>
    );
};

export default GroupedTeamMembers;

import React from 'react';
import { useState, useEffect } from "react";
import Header from './Header';
import Footer from './Footer';
import GroupedTeamMembers from './GroupedTeamMembers';
import Nav from './nav';
import NotFound from './NotFound';
import './App.css';
import {BrowserRouter as Router, Route, Routes } from 'react-router-dom';
import Employees from './Employees';

function APP ()  {

  const [selectedTeam, setTeam] = useState(JSON.parse(localStorage.getItem('selectedTeam')) || 'TeamA');

  const [employees, setEmployees] = useState(JSON.parse(localStorage.getItem('employeeList')) || [{

          id: 1, 
          fullName: "Anas Isah", 
          designation: "JavaScript Developer",
          gender: "male",
          teamName:"TeamA"
      },
      {
          id: 2, 
          fullName: "Fatima Abubakr", 
          designation: "Node Developer",
          gender: "female", 
          teamName:"TeamA"
      },
      {
          id: 3, 
          fullName: "Hajru Buhari", 
          designation: "Java Developer",
          gender: "female",
          teamName:"TeamA"
      },
      {
          id: 4, 
          fullName: "Kabir Musa", 
          designation: "React Developer",
          gender: "male", 
          teamName:"TeamB"
      },
      {
          id: 5, 
          fullName: "David Henry", 
          designation: "DotNet Developer",
          gender: "male",
          teamName:"TeamB"
      },
      {
          id: 6, 
          fullName: "Sarah Blake", 
          designation: "JavaScript Developer",
          gender: "female", 
          teamName:"TeamB"
      },
      {
          id: 7, 
          fullName: "Tukur Isah", 
          designation: "Angular Developer",
          gender: "male",
          teamName:"TeamC"
      },
      {
          id: 8, 
          fullName: "Musa Sani", 
          designation: "API Developer",
          gender: "male", 
          teamName:"TeamC"
      },
      {
          id: 9, 
          fullName: "AIsah Isah", 
          designation: "C   Developer",
          gender: "female",
          teamName:"TeamC"
      },
      {
          id: 10, 
          fullName: "Lawal Anas", 
          designation: "Python Developer",
          gender: "male", 
          teamName:"TeamD"
      },
      {
          id: 11, 
          fullName: "Jameel Wubni", 
          designation: "Vue Developer",
          gender: "male",
          teamName:"TeamD"
      },
      {
          id: 12, 
          fullName: "Abdul Nasir", 
          designation: "Graphic Designer",
          gender: "male", 
          teamName:"TeamD"
      }]);
      // It is going to change the state of employee when selected
      useEffect(() => {
        localStorage.setItem('employeeList',JSON.stringify(employees));
      },[employees]);
      // It is going to change the state of team when slected
      useEffect(() => {
        localStorage.setItem('selectedTeam',JSON.stringify(selectedTeam));
      },[selectedTeam]);

  function handleTeamSelectionChange(event){
      console.log(event.target.value);
      setTeam(event.target.value);
  }

  function handleEmployeeCardClick(event){
      const transformedEmployees = employees.map((employee) => employee.id === parseInt(event.currentTarget.id)
          ?(employee.teamName === selectedTeam)?{...employee, teamName: ''}:{...employee, teamName: selectedTeam}
          :employee);
      setEmployees(transformedEmployees);
  }; 
  return (
      <Router>
        <Nav />
        <Header 
              selectedTeam={selectedTeam}
              teamMemberCount={employees.filter((employee) => 
                employee.teamName === selectedTeam).length
              }
        />
            <Routes>
                <Route path='/'
                        element={<Employees employees={employees}
                        selectedTeam={selectedTeam}
                        handleEmployeeCardClick={handleEmployeeCardClick}
                        handleTeamSelectionChange={handleTeamSelectionChange} 
                        />}>
                </Route>
                <Route path='/GroupedTeamMembers' element={<GroupedTeamMembers 
                    employees={ employees} selectedTeam= {selectedTeam} 
                    setTeam= {setTeam} />} >
                </Route>
                <Route path='*' element={<NotFound />} >
                </Route>
            </Routes>
        <Footer />
      </Router>
  );
             
};

export default APP;

CodePudding user response:

on the first line of the GroupedTeamMembers component, you define groupedEmployees (the thing you attempt to call .map on) like so:

const [groupedEmployees, setGroupedData] = useState(groupTeamMembers);

This groupTeamMembers function gets invoked by useState on the first render to initialize groupedEmployees. The groupTeamMembers function, however, never returns a value, so groupedEmployees will be initialized to undefined.

My guess is that you want to add a return teams; statement at the end of the groupTeamMembers function.

CodePudding user response:

Hooks in react are asynchronous so there's no guarantee that groupedEmployees will be set at the beginning before the first render so it could be undefined. Also, the function groupTeamMembers isn't returning anything so the value would always be undefined.

The best approach would be to place groupTeamMembers function inside a use Effect which runs only once and sets the state that way.

UseEeffect(() => {

function groupTeamMembers() {
        var teams = [];

        var teamAMembers = employees.filter((employee) => employee.teamName === 'TeamA');
        var teamA = { team: 'TeamA', members: teamAMembers, collapsed: selectedTeam === 'TeamA'?false:true}
        teams.push(teamA);

        var teamBMembers = employees.filter((employee) => employee.teamName === 'TeamB');
        var teamB = { team: 'TeamB', members: teamBMembers, collapsed: selectedTeam === 'TeamB'?false:true}
        teams.push(teamB);

        var teamCMembers = employees.filter((employee) => employee.teamName === 'TeamC');
        var teamC = { team: 'TeamC', members: teamCMembers, collapsed: selectedTeam === 'TeamC'?false:true}
        teams.push(teamC);

        var teamDMembers = employees.filter((employee) => employee.teamName === 'TeamD');
        var teamD = { team: 'TeamD', members: teamDMembers, collapsed: selectedTeam === 'TeamD'?false:true}
        teams.push(teamD);
        return teams;
    }   
 setGroupedData(groupTeamMembers());
}, []) 

One more thing is to check the value of groupedEmployees before rendering and don't set the state to anything at the beginning


const [groupedEmployees, setGroupedData] = useState();

    return (
        <main className="container">
           {
            groupedEmployees && groupedEmployees.map((item) => {
                return (
                    <div key ={item.team} className='card mt2' style={{cursor:"pointer"}} onClick={handleTeamClick}>
                        <h4 id={item.team} className="card-header text-secondary bg-white">
                            Team Name: {item.team}
                        </h4>
                        <div id={"collapse_"   item.team}
                            className={item.collapsed === true?"collap": ""}>
                            <hr />
                            {
                                item.members.map(member => {
                                    return (
                                        <div className="mt-2">
                                            <h5 className="card-title mt-2">
                                                <span className="text-dark">Full Name: {member.fullName}</span>
                                            </h5>
                                            <p>Designation: {member.designation}</p>
                                        </div>
                                    )
                                })
                            }
                        </div>
                    </div>
                )
            }) 
           }
  • Related