Home > Software engineering >  Render multiple array in reactjs
Render multiple array in reactjs

Time:11-27

Hi I am getting two array of objects from APi and trying to render in a table, using spread operator i am combining the two arrays and binding but the problem is in table it is rendering two times how to combine the two arrays and print as one value in table for one email Id as emailid is unique in both the arrays.

Below is the code and attached link of stackblitz:

export default function App() {
  const [allData, setAllData] = useState([]);
  let data = {
    status: 'success',
    Candidates: [
      {
        Recruiter: 'Pradeep',
        Email: '[email protected]',
        Total: 11,
        Hired: 2,
        interviewscheduled: 0,
        clientsubmitted: 1,
        Withdrawn: 0,
        Onhold: 5,
        inprocess: 0,
        Rejected: 1,
        Available: 0,
        tobeupdated: 2,
      },
      {
        Recruiter: 'Sudhir',
        Email: '[email protected]',
        Total: 6,
        Hired: 1,
        interviewscheduled: 0,
        clientsubmitted: 1,
        Withdrawn: 0,
        Onhold: 1,
        inprocess: 0,
        Rejected: 0,
        Available: 0,
        tobeupdated: 3,
      },
    ],
    Jobopenings: [
      {
        Recruiter: 'Pradeep',
        Email: '[email protected]',
        jobopeningTotal: 4,
      },
      {
        Recruiter: 'Sudhir',
        Email: '[email protected]',
        jobopeningTotal: 7,
      },

      {
        Recruiter: 'Marry Scott',
        Email: '[email protected]',
        jobopeningTotal: 1,
      },
    ],
  };

  useEffect(() => {
    let data1 = [...data.Candidates, ...data.Jobopenings];
    setAllData(data1);
  }, []);

  return (
    <div>
      <table >
        <thead>
          <tr>
            <th scope="col">Recruiter Name</th>
            <th scope="col">Job Openings</th>
            <th scope="col">Hired Candidates</th>
            <th scope="col">Candidates</th>
            <th scope="col">Clients' Submissions</th>
            <th scope="col">Interviews Scheduled</th>
          </tr>
        </thead>
        {allData?.map((eachItem, index) => {
          return (
            <tbody>
              <tr key={eachItem.Email}>
                <td scope="row">{eachItem.Recruiter}</td>
                <td>{eachItem.jobopeningTotal}</td>
                <td>{eachItem.Hired}</td>
                <td>{eachItem.Total}</td>
                <td>{eachItem.clientsubmitted}</td>
                <td>{eachItem.interviewscheduled}</td>
              </tr>
            </tbody>
          );
        })}
      </table>
    </div>
  );
}

https://stackblitz.com/edit/react-vzlp1c?file=src/App.js,src/style.css

CodePudding user response:

You want some way to merge the 2 arrays together such that items with repeated Keys (Email in your case) get combined and others get inserted. You can probably find a bunch of libs that already have such helper functions, or you can write a short one yourself.

This should do what you want:

useEffect(() => {
    function merge(arrayOne, arrayTwo, key) {
      let result = [...arrayOne];
      arrayTwo.forEach((entryTwo) => {
        let existing = result.find((entry) => entry[key] === entryTwo[key]);
        if (existing) {
          Object.assign(existing, entryTwo);
          return;
        }
        result.push(entryTwo);
      });
      return result;
    }
    setAllData(merge(data.Candidates, data.Jobopenings, 'Email'));
  }, []);

CodePudding user response:

you can use lodash for it

let result = _.unionBy(data.Candidates, data.Jobopenings, "Email")
result =result.map((item,index)=>{ 
return {...item, jobopeningTotal:_.find(data.Jobopenings,{Email:item.Email}).jobopeningTotal }
})

console.log("Your desired output",result);

Thank you!

CodePudding user response:

You can create a temporary object obj1 with Array.prorotype.map() and Array.prorotype.reduce() from the arrays data.Candidates and data.Jobopenings but keeping track of the repeated data by Email and finally get the result array value with Object.values()

Code:

useEffect(() => {
  const obj1 = [...data.Candidates, ...data.Jobopenings]
    .map((o) => ({
      Email: o.Email,
      Recruiter: o.Recruiter,
      jobopeningTotal: o.jobopeningTotal || 0,
      Hired: o.Hired || 0,
      Total: o.Total || 0,
      clientsubmitted: o.clientsubmitted || 0,
      interviewscheduled: o.interviewscheduled || 0,
    }))
    .reduce((a, c) => {
      a[c.Email] = a[c.Email] || {
        Email: c.Email,
        Recruiter: c.Recruiter,
        jobopeningTotal: 0,
        Hired: 0,
        Total: 0,
        clientsubmitted: 0,
        interviewscheduled: 0,
      };
      a[c.Email].jobopeningTotal  = c.jobopeningTotal;
      a[c.Email].Hired  = c.Hired;
      a[c.Email].clientsubmitted  = c.clientsubmitted;
      a[c.Email].interviewscheduled  = c.interviewscheduled;
      a[c.Email].Total  = c.Total;
      return a;
    }, {});
  const data1 = Object.values(obj1);

  setAllData(data1);
}, []);

And here is teh Stackblitz: https://stackblitz.com/edit/react-wy9d7t?file=src/App.js

  • Related