Make a new row when reach to 6 columns

Viewed 77

I have a problem regarding my code where I can not output the mapping into 6 columns in the table. So what I want is that whenever the data reach 6 columns it will create a new row. Below is my code:

 import React from "react";
import { useEffect, useState } from "react";
import timestamp from "unix-timestamp";

export const Result = (code) => {
const [output, setOutput] = useState([]);
const [time, setTime] = useState([]);
const [data, setData] = useState([]);
const [hari, setHari] = useState([]);
useEffect(() => {
 getWaktuSolat();
 outputList();
 setData([]);
}, [code.code]);

var requestOptions = {
 method: "GET",
 redirect: "follow",
};
async function getWaktuSolat() {
 await fetch("https://mpt.i906.my/api/prayer/" + code.code, requestOptions)
   .then((response) => response.json())
   .then((result) => {
     console.log(result.data);
     setOutput(result.data);
     setTime(result.data.times);
     console.log(time);
   })
   .catch((error) => console.log("error", error));
}
function outputList() {
 for (let x = 0; x < time.length; x++) {
   for (let z = 0; z < 6; z++) {
     let j = timestamp.toDate(time[x][z]);
     data.push(j.toString().slice(15, 21));
     console.log(data);
   }
 }
}
outputList();
return (
 <div className="Result">
   <h1>{output.place}</h1>
   <table>
     <th>Subuh</th>
     <th>Syuruk</th>
     <th>Zuhur</th>
     <th>Asar</th>
     <th>Maghrib</th>
     <th>Isyak</th>
     <tr>
       {data.map((item, index) => (
         <td>{item}</td>
       ))}
     </tr>
   </table>
 </div>
);
};
export default Result;

This is my output

enter image description here

2 Answers

EDIT: In order to not use a ternary conditional inside the return call and ensure that every <tr> can detect its corresponding </tr>, I split the rendering of the table as follows:

const renderTable = (data) => {
  const rows = [];
  for (let i = 0; i < data.length; i += 6) {
    rows.push(<tr key={i}>{renderRow(data.slice(i, i + 6))}</tr>);
  }
  return rows;
};

const renderRow = (row) => {
  return row.map((element) => <td key={element}>{element}</td>);
};

A new row will be created every sixth element, without the possibility of a final empty row. You can see it in action in this JSFiddle.

ORIGINAL: In order to trigger a new row every six columns, you can use the remainder % on the index. Noting that index starts at 0, each item that should be placed on a new row will have an index divisible by 6, that is index % 6 === 0. On such an item, close the previous row and start another row:

<table>
  <th>Subuh</th>
  <th>Syuruk</th>
  <th>Zuhur</th>
  <th>Asar</th>
  <th>Maghrib</th>
  <th>Isyak</th>
  <tr>
  {data.map((item, index) => (
    if (index % 6 === 0) {
      return <td>{item}</td></tr><tr>
    } else {
      return <td>{item}</td>
    })
  }
  </tr>
</table>

A downside to this approach is that if the number of data cells is a multiple of 6, then the table will end with an empty row. To fix this, return the final <tr> unless data.length % 6 === 0, and do not start a new row for the last element of data, i.e., index === data.length - 1.

You have to put the tr element inside the loop.
I have provided the algorithm but the syntax maybe wrong because I am not familiar with React.

<table>
  <th>Subuh</th>
  <th>Syuruk</th>
  <th>Zuhur</th>
  <th>Asar</th>
  <th>Maghrib</th>
  <th>Isyak</th>
  {data.map((item, index) => (
    if (index % 6 === 0) {
      // Start a new row if first element
      return <tr><td>{item}</td>
    } else if (index % 6 === 5) {
      // End the row if last element
      return <td>{item}</td></tr>
    } else {
      // just insert item if middle
      return <td>{item}</td>
    })
  }
</table>
Related