0

I have two react components. In which one of the components processes the CSV data using Papa Parse and another one renders the data table. I am using the first component to parse and send the data to the second component using this.props.

Here, I'm using the Jquery data table to render the CSV data in the web. Problem is I'm unable to render the data inside the data table using this.props. (this issue has been resolved by @drew-reese)

Also is it possible to render graph as defaultContent API option in data table? Please refer to second component.

Here Is What I'm trying,

First component:

var output = [];
class Tables extends React.Component {

    constructor(props) {
      super(props);
      this.state = {
          data: []
        }
      this.updateData = this.updateData.bind(this);
    }
    componentWillMount() {

      var csvFilePath = require("../data/input.csv");
      Papa.parse(csvFilePath, {
        header: true,
        download: true,
        skipEmptyLines: true,
        complete: this.updateData
      });
    }
    updateData(result) {
      output = result.data;
      output = output.map(obj => Object.values(obj));
      console.log(output) //this works
    this.setState({data: output})    
    }
    render() { 
        return(
            <div>
                <Charts data={this.state.data}/>
            </div>
        )
    }
  }
  export default Tables;

Second comp

import { Line } from 'react-chartjs-2';
const $ = require('jquery')
$.DataTable = require('datatables.net');
class Charts extends React.Component {

    componentDidMount() {
        console.log(this.el);
        this.$el = $(this.el)
        this.$el.DataTable({
            data: this.props.data,
            columns: [
                { title: "heading" },
                { title: "heading" },
                { title: "heading " },
                { title: "heading " },
                { title: " heading",\
                  defaultContent: <Line /> #chartjs graph
                 },
            ]
        })
    }
    componentWillUnmount() {
    }
    render() {
        return (
            <div>
                <table className="display" width="100%" ref = {el => this.el = el }></table>
                <p>{this.props.data}</p>
            </div>
        );
    }
}

//ChartJS line graph
<Line
    data={data}
    options={options} />

I have tried to display the same data inside a p tag, but not working. Actually i'm unable to pass the data from one component to another. Any ideas? Do I have to use any async or something. Or is there any better way to parse csv and display in a data table?

Is it possible to render a chart inside one of the columns in the data table? Please refer to the last column and defaultContent API section.

Thanks in advance.

7
  • Does changing hook changed anything componentDidMount instead of componentWillMount ? Commented Mar 18, 2020 at 7:28
  • I changed componentWillMount to componentDidMount. Still the data table is empty. Commented Mar 18, 2020 at 7:37
  • Are you saying this.props.data isn't rendering within the <p> element? Or it is and the table isn't rendering the jquery data as expected? Commented Mar 18, 2020 at 7:52
  • this.props.data is the data for the data table. I checked by putting the data inside the data table and p tag. Both are actually not working. Commented Mar 18, 2020 at 7:57
  • 1
    Awesome, that was what I suspected needed to be added. Unhid my answer. Commented Mar 19, 2020 at 2:21

1 Answer 1

1

I suspect it is because jquery operates outside of react and your child component only sets the table when it mounts. When the parent sets state with data the child sees the prop update and rerenders <p>{this.props.data}</p>, but the <table /> does not get its data updated. If you refactor the jquery logic into utility functions and call the set data table in componentDidMount and update table in componentDidUpdate props update, you can take advantage of the component lifecycle functions to get the <table /> data updated.

Using this Link this is an example of how your DataTable could be updated.

setDataTable = () => {
  this.$el = $(this.el);
  this.$el.DataTable({
    data: this.props.data,
    columns: [
      { title: "heading" },
      { title: "heading" },
      { title: "heading " },
      { title: "heading " },
      { title: " heading" },
    ]
  });
}

updateDataTable = () => {
  const table = $(this.el).DataTable();

  // logic to update table with updated data
  table.clear();
  table.rows.add(this.props.data);
  table.draw();
};

componentDidMount() {
  console.log(this.el);
  this.setDataTable();
}

componentDidUpdate(prevProps) {
  console.log(this.el);
  if (prevProps.data !== this.props.data) {
    this.updateDataTable();
  }
}

Question Why not use a more react way of rendering your data? Something like MUI-Datatables?

Sign up to request clarification or add additional context in comments.

3 Comments

There is no data inside the data table when using this method. I was getting an error of setDataTable not defined. So I tried setting this.setDataTable = this.setDataTable.bind(this) in the constructor. But still no data inside the data table. Also data table creates an error message namely can't reinitialise the table. Earlier I was able to render the table using componentDidUpdate.
@Musthafa Ah, it's an instance function, so would be accessed as this.setDataTable(), updated. It's also an arrow function so you shouldn't need to bind this to it in the constructor. About initializing, or reinitializing, the DataTable, that I'm unsure of but can try some quick research about updating the data to improve my answer. I suspect when updating you don't need the columns.
Yeah, this is a great way of rendering data table inside react component. We can easily re-render the table with the latest data. As of now, there is no problem with re-initialization. I'll check with updating the data. I'm also trying to render a graph inside one of the columns. is it possible? I'm getting an error of [object Object]. Anyway thanks for the answer update.

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.