0

I want to use the following data

[
  {
      "id": "1",
      "label": "Score",
      "tabledata": [ 
        {"label": "Day 1", "data": {"score": 73}},
        {"label": "Day 2", "data": {"score": 64}},
      {"label": "Day 3", "data": {"score": 72}}
      ]
  }, {
      "id": "2",
      "label": "Success",
      "tabledata": [ 
        {"label": "Day 1", "data": {"score": 73 }},
        {"label": "Day 2", "data": {"score": 64 }},
        {"label": "Day 3", "data": {"score": 72}}
      ]
  } ]

<table>
  <tr>    
    <td>
    
    </td>
    <td>
     Score
    </td>
    <td>
     Success
    </td>
   
  </tr>
  
   <tr>    
    <td>
      Day 3
    </td>
    <td>
     72
    </td>
    <td>
     72
    </td>
   
  </tr>
  
   <tr>    
    <td>
      Day 2
    </td>
    <td>
     64
    </td>
    <td>
     64
    </td>
   
  </tr>
 <tr>    
    <td>
      Day 1
    </td>
    <td>
     73
    </td>
    <td>
     73
    </td>
    
  </tr>
  </table>

The solution i came up is:

 <table >
        <tr>
          <td> </td>
          <td>
            {this.props.GraphData[0].label}
          </td>
          <td>
            {this.props.GraphData[1].label}
          </td>

</tr> 
<tr>
          <td> </td>
          <td>
            {this.props.GraphData[0].tabledata.data.map(row => ([ <tr key={i}>  <td>  {row.score}</td> </tr> )])};
          </td>
          <td>
            {this.props.GraphData[1].tabledata.data.map(row => ([ <tr key={i}>  <td>  {row.score}</td> </tr> )])};
          </td>

</tr> 
</table>

How can I turn with reverse.map the values to appear in descending order (the first row (day 3) and last row (day 1). Finally is there a way to avoid using [0] or [1] from the data file but to use mapping for all the rows and columns of the table?

6
  • I'm not exactly sure what you are trying to render out as the final result, but I threw this fiddle together that reverses the order: jsfiddle.net/gkysmsqz/31. Let me know if this is what you are looking for? Your code needs a serious refactor, it needed a lot of work to get it running. Commented Feb 23, 2018 at 21:48
  • Or maybe this?? jsfiddle.net/gkysmsqz/35 Commented Feb 23, 2018 at 21:52
  • @Chase DeAnda thank you ut looks like it's working in JsFiddle but in my app it now has the following issue` TypeError: Cannot read property '0' of undefined` Commented Feb 23, 2018 at 22:17
  • Can you post your full code? Are you passing in the data as a prop GraphData? Commented Feb 23, 2018 at 22:25
  • Exactly i used conditional rendering, so it will only render the element only when it's defined, so i use {this.props.rowData[0] && ( <td> {this.props.rowData[0].label} </td> )} consider GraphData = rowData[0], but now the table won't show on screen. Commented Feb 23, 2018 at 22:41

1 Answer 1

1

first of all, your data structure is adding complexity as hell, and i advice you to structure it well so you could easily consume it, I've made a refactoring for your code and also restructured your data with a generic way so even day4, ...dayn could be shown, that shows well how complex the consumption became if we think generically, so this is what I've got, so rename this file as Table.jsx and try to import it as so import Table from './Table';:

import React from 'react';
import { get, map, reduce, uniq, find, orderBy } from 'lodash';

const data = [
  {
    id: '1',
    label: 'Score',
    tabledata: [
      { label: 'Day 1', data: { score: 73 } },
      { label: 'Day 2', data: { score: 64 } },
      { label: 'Day 3', data: { score: 72 } },
      { label: 'Day 5', data: { score: 60 } }
    ]
  },
  {
    id: '2',
    label: 'Success',
    tabledata: [
      { label: 'Day 1', data: { score: 73 } },
      { label: 'Day 2', data: { score: 64 } },
      { label: 'Day 3', data: { score: 73 } }
    ]
  }
];

const columnsHeaders = ['day', ...map(data, 'label')];

const days = uniq(
  reduce(
    data,
    (acc, item) => [...acc, ...map(get(item, 'tabledata'), 'label')],
    []
  )
);

const restructuredData = reduce(
  days,
  (acc, day) => {
    const dayData = reduce(
      map(data, 'label'),
      (dayDataAcc, colName) => {
        return {
          ...dayDataAcc,
          day,
          [colName]: get(
            find(get(find(data, { label: colName }), 'tabledata'), {
              label: day
            }),
            ['data', 'score']
          )
        };
      },
      {}
    );
    return [...acc, dayData];
  },
  []
);

const sortedData = orderBy(restructuredData, 'day', 'desc');

const TableHeaders = () => (
  <thead>
    <tr>{map(columnsHeaders, (col, index) => <th key={index}>{col}</th>)}</tr>
  </thead>
);

// checking our data
console.log('restructuredData', restructuredData);
console.log('sortedData', sortedData);

const TableRows = ({ data }) => (
  <tbody>
    {map(data, ({ day, Score: score, Success: success }) => (
      <tr key={day}>
        <td>{day || '-'}</td>
        <td>{score || '-'}</td>
        <td>{success || '-'}</td>
      </tr>
    ))}
  </tbody>
);

export default () => (
  <table>
    <TableHeaders />
    <TableRows data={sortedData} />
  </table>
);
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you for the answer, but I must load the json file as it (it's not created by me)
I got it, in this case it's quite tough, especially if you have dynamic data as you see. but it's OK in think.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.