Search code examples
node.jsreactjsarraysjsonresponse

Convert an object into a key value pair in JSON


I've been trying to render my API response from Nodejs to display on my react table. I want to perform some calculations and filter out a few things on the response from the API response. But later while trying to display it on my tables, I'm having complications. I know its a pretty simple task but I'm unable to come up with the proper logic or approach for this. Thank you for helping out.

.then(response => {
            console.log(response);
            const result = response.data.rows;
            setRes(result)
            var arr = [];
            Object.keys(result).forEach(function(key) {
              arr.push(result[key]);
            });
  
            const filtered = {
                Greeters: 
                  { 
                    nvCount: 0,
                    Taken: 0,
                    vCount: 0
                  },
                Cleaning:{
                  nvCount: 0,
                  Taken: 0,
                  vCount: 0,
                  
                },
                Intercession:{
                  
                  nvCount: 0,
                  Taken: 0,
                  vCount: 0,
                },
                
                Media:{
                  
                  nvCount: 0,
                  Taken: 0,
                  vCount: 0,
                },
                KidsChurch:{
                  
                  nvCount: 0,
                  Taken: 0,
                  vCount: 0,
                },
  
            };
            arr.map((el, i) => {
              if (el.team.includes('Greeters')) {
                if (el.preference.includes('NON-VEG')) {
                  filtered.Greeters.nvCount++; 
              }
              else if (el.preference.includes('VEG')) {
                filtered.Greeters.vCount++;
              }
              if (el.taken===true ) {
                filtered.Greeters.Taken++;
              }
              
              }
              else if (el.team.includes('Cleaning')) {
                if (el.preference.includes('NON-VEG')) {
                  filtered.Cleaning.nvCount++;
              }
              else if (el.preference.includes('VEG')) {
                filtered.Cleaning.vCount++;
              }
              if (el.taken===true ) {
                filtered.Cleaning.Taken++;
              }
              
              }
              else if (el.team.includes('Intercession')) {
                if (el.preference.includes('NON-VEG')) {
                  filtered.Intercession.nvCount++;
              }
              else if (el.preference.includes('VEG')) {
                filtered.Intercession.vCount++;
              }
              if (el.taken===true ) {
                filtered.Intercession.Taken++;
              }
              }
              
              else if (el.team.includes('Media')) {
                if (el.preference.includes('NON-VEG')) {
                  filtered.Media.nvCount++;
              }
              else if (el.preference.includes('VEG')) {
                filtered.Media.vCount++;
              }
              if (el.taken===true ) {
                filtered.Media.Taken++;
              }
              }
              else if (el.team.includes('Kids Church')) {
                if (el.preference.includes('NON-VEG')) {
                  filtered.KidsChurch.nvCount++;
              }
              else if (el.preference.includes('VEG')) {
                filtered.KidsChurch.vCount++;
              }
              if (el.taken===true ) {
                filtered.KidsChurch.Taken++;
              }
              }
          });

The response data from the API:

0
: 
{id: '56', name: 'Prajwal V', phone: '990*******', preference: 'NON-VEG', team: 'Greeters', taken: false}
1
: 
{id: '57', name: 'Amulya', phone: '63605******', preference: 'NON-VEG', team: 'Greeters', taken: true}
2
: 
{id: '58', name: 'Devika', phone: '8618******', preference: 'NON-VEG', team: 'Greeters', taken: false}
3
: 
{id: '59', name: 'Guru', phone: '9019*****', preference: 'NON-VEG', team: 'Greeters', taken: true}
4
: 
{id: '60', name: 'Peter', phone: '9988*****', preference: 'VEG', team: 'Cleaning', taken: false}

I just want to find out the count("NON-VEG"), count("VEG"), and count(taken) for each team. And I want to display these based on a SELECT dropdown that chooses the Team. eg: Select: 'Greeters', the count("NON-VEG"), count("VEG"), and count(taken) for 'Greeters' must be displayed in tabular format.

Current attempt,

    <Select
              className='SelectTeam'
              closeMenuOnSelect={true}
              components={animatedComponents}
              isMulti={false}
              options={teams}
              name='team'
              onChange={handleSelect}
            />
    {res.map(el => {
        return(
        <div>
        {team == el.team && 
        <tr key={el.team}>
            <td>{el.name}</td>
            <td>{el.preference}</td>
        </tr>
        }
                
                </div>

          )
        })

}

The data in the 'filtered' object has all the necessary data needed. In other words, I just need to display that filtered data based on the team selected or tell me a better approach to handle this complication Thank you so much for helping out.


Solution

  • You can construct the filtered object dynamically like below code

    let filtered = {};
    teams.map(team=>{
      filtered[team.name] = {
          nvCount: 0,
          Taken: 0,
          vCount: 0,
      };
    });
    result.map(user => {
      if (user.preference.includes("NON-VEG")) {
        filtered[user.team].nvCount += 1;
      } else if (user.preference.includes('VEG')) {
        filtered[user.team].vCount += 1;
      }
      if (user.taken === true) {
        filtered[user.team].Taken += 1;
      }
    });
    console.log(filtered);
    setFilteredData(filtered);
    

    Your filtered object would look like this,

    {
    "Greeters": {
        "nvCount": 4,
        "Taken": 2,
        "vCount": 0
    },
    "Cleaning": {
        "nvCount": 0,
        "Taken": 0,
        "vCount": 1
    }
    }
    

    store it in filteredData state and display it

    {selectedTeam && (
        <>
          <div>NV count: {filteredData[selectedTeam].nvCount}</div>
          <div>Veg count: {filteredData[selectedTeam].vCount}</div>
          <div>Taken: {filteredData[selectedTeam].Taken}</div>
        </>
      )}
    

    selectedTeam is the selected data from your select box.