Skip to content

Loop through array of objects and display them in react component

I have an array of object as follows. The data is based on created_date for e.g. (“2021-09-12”)

As you can see, i have got last 5 days of data. i.e. 12th Sep, 11th Sep, 10th Sep, 9th Sep and 8th Sep. The response does not have any data for 11th sept and 8th Sept.

const buildData = [
    {
      "project_id": "1H16SET9829",
      "created_date": "2021-09-12",
      "status": "P"
    },
    {
      "project_id": "1J01SET10974",
      "created_date": "2021-09-10",
      "status": "F"
    },
    {
      "project_id": "1J01SET10971",
      "created_date": "2021-09-09",
      "status": "P"
    },
    {
      "project_id": "1J01SET10969",
      "created_date": "2021-09-09",
      "status": "F"
    }
]

Based on this above information, i have to display data in UI using react functional component as follows

  Sep 12, 2021  | Sep 11,2021 |   Sep 10, 2021   |   Sep 09, 2021    | Sep 08, 2021
1H16SET9829 (P) |             | 1J01SET10974 (F) | 1J01SET10971 (P)  |
                |             |                  | 1J01SET10971 (F)  |

Can someone please let me know how to achieve this. I tried the following but it doesnot display the correct data. I am not getting how to display correct project_id below its date. Also some dates have 2 project_ids in it. for e.g. Sep 09,2021 has 2 project_ids and both need to be displayed one below the other and then proceed with next date.

const renderProjects = (props) => {
    const items = buildData.map( (t, idx) => (
        <>
          <div>{ t.created_date }</div>
          <div>{t.project_id</div>
        </>
    ))

    return (
        <div className="project-list">
            { items }
        </div>
    )
}

Answer

You can do something like this (see inline comments):

const buildData = [
    {
        project_id: '1H16SET9829',
        created_date: '2021-09-12',
        status: 'P',
    },
    {
        project_id: '1J01SET10974',
        created_date: '2021-09-10',
        status: 'F',
    },
    {
        project_id: '1J01SET10971',
        created_date: '2021-09-09',
        status: 'P',
    },
    {
        project_id: '1J01SET10969',
        created_date: '2021-09-09',
        status: 'F',
    },
];

export const RenderProjects = (props) => {
    // convert the buildData into a map from date -> list of `{project_id, status}`s
    const buildDataByDate = buildData.reduce((map, project) => {
        const projectInfo = {
            project_id: project.project_id,
            status: project.status,
        };
        if (!map[project.created_date]) {
            map[project.created_date] = [projectInfo];
        } else {
            map[project.created_date].push(projectInfo);
        }
        return map;
    }, {});


    // find the first and last dates
    const minDate = Object.keys(buildDataByDate).sort()[0];
    const maxDate = Object.keys(buildDataByDate).sort().reverse()[0];
    // find how many days are between them
    const daysBetween =
        (Date.parse(maxDate) - Date.parse(minDate)) / (24 * 60 * 60 * 1000);
    // add in the missing dates
    [...Array(daysBetween).keys()].forEach((increment) => {
        const dateToAdd = new Date(
            Date.parse(minDate) + increment * 24 * 60 * 60 * 1000,
        )
            .toISOString()
            .substring(0, 10);
        if (!buildDataByDate[dateToAdd]) {
            buildDataByDate[dateToAdd] = [];
        }
    });

    // render something for each entry in that map
   const items = Object.entries(buildDataByDate)
        .sort((a, b) => {
            return Date.parse(b[0]) - Date.parse(a[0]);
        })
        .map(([date, projects]) => {
            return (
                <React.Fragment key={date}>
                    <div>{date}</div>
                    {projects.map((project) => {
                        return (
                            <div
                                key={project.project_id}
                            >{`${project.project_id} (${project.status})`}</div>
                        );
                    })}
                </React.Fragment>
            );
        });

    return <div className='project-list'>{items}</div>;
};