0

So I need to make a table where each product corresponds to a cell; however, there's something with the JSX that prevents me from returning jsx when I don't close the tags in the returned JSX. I am not sure if there are alternate methods, but it seems that I am in a kind of bind, because the error message doesn't make sense and I get things like unexpected token.

Tried to return the JSX with map inside the callback, but it seems I can't do exactly what I want.

       {props.products.slice(0, 50).map((element, i) => {
          console.log(element.name);
          if (i % 5 == 0) {
            return (
              <TableRow>
                <TableRowColumn>{element.name}</TableRowColumn>
            )

          } else if (i % 5 == 4) {

            return (
                <TableRowColumn>{element.name}</TableRowColumn>
              </TableRow>
            )

          } else {

            return (
                <TableRowColumn>{element.name}</TableRowColumn>
            )

          }

        })}

I expect each row to have 5 columns, and each cell containing a product and the table containing 50 elements. Basically, I want to close the row after 5 column.

I would like to have something like a 5 by 5 table in the end or 5 by 10 to be exact.

aLex
  • 1
  • 11

2 Answers2

0

You can check some examples on material-ui site (https://material-ui.com/demos/tables/)

If you know which elements are headers names you can use for-loop over products to create columns name e.g.

<TableRow>
  {props.products.map((product, index) => {
    if (index % 5 === 0) {
      return <TableCell>{product.name}</TableCell>;
    }
  }
</TableRow>
Igor Staszewski
  • 401
  • 2
  • 8
  • 1
    Just adapt it, very simple –  Apr 04 '19 at 19:40
  • 1
    I think the only solution is to iterate by chunks of 5. – aLex Apr 04 '19 at 19:41
  • 1
    It looks really similar in v0: {props.products.map((product, index) => { if (index % 5 === 0) { return {product.name}; } } – Igor Staszewski Apr 04 '19 at 19:44
  • Also, you didn't understand the question. I want to create a 5 by 5 table and do it in a single loop. I am not trying to create a 1 by 5 row column headers. Maybe, I should have clarified. – aLex Apr 04 '19 at 19:44
  • 1
    I understand your question. First you need to create headers, then in similar way you can iterate over your data and render rows. – Igor Staszewski Apr 04 '19 at 19:45
  • I don't have headers though. It's like a table of image without column header, that's why the solution won't work. One thing I realized though is that I only need headers at the top. I shouldn't have used headers, is there a way to do this with 1 loop and without headers? – aLex Apr 04 '19 at 19:46
0

JSX is not HTML and you cannot brake up tag pairs.

Proper solution should be like this

function chunker(array, length) {
   // select proper implementation on the link below
   return []
}
{chunker(props.products.slice(0, 50)), 5).map((chunk) => {
  if (chunk.length !== 5) {
    console.warn('not full chunk', chunk)
  }
  return (
    <TableRow>
      {chunk.map((element, i) => {
        console.log(element.name);
        return (
          <TableRowColumn>{element.name}</TableRowColumn>
        )
      })}
    </TableRow>
  )
})}

Select chunk implementation here Split array into chunks

Pavlo Zhukov
  • 3,007
  • 3
  • 26
  • 43
  • Looks like it is missed. Please check proper method here https://stackoverflow.com/questions/8495687/split-array-into-chunks – Pavlo Zhukov Apr 04 '19 at 20:00
  • uncaught at g Error: e.slice(...).chunk is not a function. Yeah, I looked at that page earlier, but I didn't want to create chunks or create a method or use a library just for this. – aLex Apr 04 '19 at 20:02
  • @tefisjb Sorry, I was confused by usage of https://stackoverflow.com/a/11638192/6625548 – Pavlo Zhukov Apr 04 '19 at 20:03
  • It's ok, I am pretty sure the only way is to use a chunk method or a for loop and iterate by chunk. – aLex Apr 04 '19 at 20:07