Home > Software design >  Show values from a nested object of objects in JavaScript
Show values from a nested object of objects in JavaScript

Time:12-12

I have a nested object of objects, I need to show some data from it. The object is:

{
"2": {
   "id": 2,
        "username": "mark",
        "position": "Director",
        "branch": "NY Branch",
        "name": "Mark Branson",
        "attendance": {
            "2022-11-01": {
                "times": [],
                "status": "holiday"
            },
            "2022-11-02": {
                "times": [
                    "11:05:31",
                    "11:51:30",
                    "12:59:50"
                ],
                "status": "late"
            },
            "2022-11-03": {
                "times": [
                    "10:24:17",
                    "11:05:20",
                    "11:10:09"                  
                ],
                "status": "late"
            },
},
"4": {
  "id": 4,
        "username": "john",
        "position": "Manager",
        "branch": "SF Branch",
        "name": "John Miller",
        "attendance": {
            "2022-11-01": {
                "times": [],
                "status": "holiday"
            },
            "2022-11-02": {
                "times": [
                    "11:05:31",
                    "11:51:30",
                    "12:59:50"
                ],
                "status": "present"
            },
            "2022-11-03": {
                "times": [
                    "10:24:17",
                    "11:05:20",
                    "11:10:09"                  
                ],
                "status": "late"
            },
},
"5": {
   "id": 5,
        "username": "emma",
        "position": "HR",
        "branch": "Head Branch",
        "name": "Emma Smith",
        "attendance": {
            "2022-11-01": {
                "times": [],
                "status": "holiday"
            },
            "2022-11-02": {
                "times": [
                    "11:05:31",
                    "11:51:30",
                    "12:59:50"
                ],
                "status": "late"
            },
            "2022-11-03": {
                "times": [
                    "10:24:17",
                    "11:05:20",
                    "11:10:09"                  
                ],
                "status": "present"
            },
},
}

The design I need to implement is this

Design

The React Code I have written so far is:

import { useEffect, useState } from "react";
import axios from "axios";

export default function App() {
  const [object, setUsers] = useState([]);

  useEffect(() => {
    const instance = axios.create({
      baseURL: "https://test.com/",
      headers: {
        Authorization: "Bearer token",
      },
    });
    const getData = async () => {
      const userData = await instance.get("/test");
      setUsers(userData.data);
    };
    getData();
  }, []);
  console.log("Object", object);
  console.log("Object.keys(object)", Object.keys(object));

  console.log("Attendance", Object.entries(object));

  let nameData = [];

  Object.keys(object).forEach(function (key) {
    console.log("Name", object[key].name);
    nameData.push(object[key].name);
  });

  console.log("nameData", nameData);

  let newAttendanceData = [];

  Object.keys(object).forEach(function (key) {
    console.log("Attendence Data", object[key].attendance);
    console.log(
      "Attendence Data of 2 Nov",
      Object.keys(object[key].attendance)[1]
    );
    console.log(
      "Attendence Data of 2 Nov value",
      Object.keys(object[key].attendance)[1]
    );
    newAttendanceData.push(object[key].attendance);
  });

  console.log("newAttendanceData", newAttendanceData);

  return (
    <div className="App">
      <div>
        <table>
          <tr>
            <th> Date</th>
            <th> Name </th>
            <th> Status </th>
          </tr>
          <tr>
            <td>
              <div>{nameData && nameData.map((name) => <div>{name}</div>)}</div>
            </td>
          </tr>
        </table>
      </div>
    </div>
  );
}

This is not properly written to show the data according to the design, what would be the proper way to map these object data so that the data can be displayed as per the design? Need a way to get data from the nested object structure.

CodePudding user response:

Why nesting id: 2 in the parent 2 to complicate your work? You can simply save them like this

{
 2: {
  "username": "mark",
  "position": "Director",
  "branch": "NY Branch",
  "name": "Mark Branson",
  ...
 },
}

or

{
 {
   "id": 2,
   "username": "mark",
   "position": "Director",
   "branch": "NY Branch",
   "name": "Mark Branson",
   ...
 },
}

Anyway I'll solve it with your data structure in a basic way. As the mockup, I see we only need the employee name, attendance date and status and we can get them like this

let newData = [];

Object.keys(object).forEach((key) => {
 const name = object[key].name;
 const attendances = object[key].attendance;
 for (let date in attendances) {
  newData.push({
   employeeName: name,
   date: date,
   status: attendances[date].status
  });
 }
});

You can push results into the newData in the way that you're comfortable to deal with, hope this help.

CodePudding user response:

Here's one way to transform that data structure into one that's easier to work with for your needs. I corrected the typos in your input data structure. It wasn't clear whether the resulting data should be sorted, or in what order, so I included a quick demonstration sorted by date:

let transformData = inp => {
  let out = [];
  for (let person of Object.values(inp)) {
    for (let date of Object.keys(person.attendance)) {
      // capture a new record: 
      out.push({
        "name": person.name,
        "date": date,
        "status": person.attendance[date].status
      })
    }
  }

  // sort here, if needed:
  out = out.sort((a, b) => {
    return a.date > b.date
  });

  return out;
}


let data = {
  "2": {
    "id": 2,
    "username": "mark",
    "position": "Director",
    "branch": "NY Branch",
    "name": "Mark Branson",
    "attendance": {
      "2022-11-01": {
        "times": [],
        "status": "holiday"
      },
      "2022-11-02": {
        "times": [
          "11:05:31",
          "11:51:30",
          "12:59:50"
        ],
        "status": "late"
      },
      "2022-11-03": {
        "times": [
          "10:24:17",
          "11:05:20",
          "11:10:09"
        ],
        "status": "late"
      },
    }
  },
  "4": {
    "id": 4,
    "username": "john",
    "position": "Manager",
    "branch": "SF Branch",
    "name": "John Miller",
    "attendance": {
      "2022-11-01": {
        "times": [],
        "status": "holiday"
      },
      "2022-11-02": {
        "times": [
          "11:05:31",
          "11:51:30",
          "12:59:50"
        ],
        "status": "present"
      },
      "2022-11-03": {
        "times": [
          "10:24:17",
          "11:05:20",
          "11:10:09"
        ],
        "status": "late"
      },
    }
  },
  "5": {
    "id": 5,
    "username": "emma",
    "position": "HR",
    "branch": "Head Branch",
    "name": "Emma Smith",
    "attendance": {
      "2022-11-01": {
        "times": [],
        "status": "holiday"
      },
      "2022-11-02": {
        "times": [
          "11:05:31",
          "11:51:30",
          "12:59:50"
        ],
        "status": "late"
      },
      "2022-11-03": {
        "times": [
          "10:24:17",
          "11:05:20",
          "11:10:09"
        ],
        "status": "present"
      },
    }
  }
}

console.log(transformData(data))

  • Related