Search code examples
javascriptreactjsreduxreact-reduxblueprintjs

How to render a table with blueprintjs/table


I'm attempting to display a json array of data within a blueprintjs table. The table should be dynamic in it's rendering (number of rows and columns), so to display whatever is in the json array. In production, the json array will come from an API call, but to start off with, I'm just trying to get it working on some dummy data.

I've managed to generate the table dynamically and display the column headers, however I'm stuck on generating the actual data cells.

Here's my code so far:

interface ResultsTableProps {}
interface ResultsTableState {
    numResultsRows? : number,
    results
}

export default class ResultsTable extends React.Component 
<ResultsTableProps, ResultsTableState> {

    public state: ResultsTableState = {
        numResultsRows: 0,
        results: null
    }

    componentDidMount() {
        var searchString = store.getState().submitSearch.searchString;

        // Pretend an API call just happened and the results object is returned

        // This is the dummy data
        var resultsObject = getData();
        this.setState({
            numResultsRows: resultsObject.length,
            results: resultsObject
        });
    }

    private createColumn(columnData) {
        return <Column name={columnData} />
    }

    private createColumns(columnDatas) {
        return Object.keys(columnDatas[0]["_source"]).map(this.createColumn);
    }

    private createTable(results, numResultsRows) {
        return (
            <Table numRows={numResultsRows}>
                {this.createColumns(results)}
            </Table>
        );
    }

    render() {
        return (            
            <div id="results-table">
                <Card interactive={false} elevation={Elevation.TWO} className={"pt-dark"}>
                    {this.createTable(this.state.results, this.state.numResultsRows)}
                </Card>
            </div>
        );
    }
}

When this code runs, I get a table, with the correct number of rows and the correct number of columns, and also with correct column headers.

I now need to somehow fill in the rows with the cells/data, and I'm stuck. I'm not sure how I should go about this.

How can it be done?

In case you'd like to see the dummy data:

[
{
    "_type": "location",
    "_id": "5sXFcmEBsayGTsLx1BqB",
    "_source": {
      "elevation": "",
      "country": "ZA",
      "geonameid": "958386",
      "timezone": "Africa/Johannesburg",
      "latitude": "-27.17494",
      "mod_date": "2014-10-01",
      "dem": "968",
      "admin1_fips": "08",
      "population": "0",
      "alternatenames": "",
      "feature_class": "S",
      "geohash": "k7pt6ubwx0n0",
      "name": "Sahara",
      "alt_cc": "",
      "fulltext": "ZA 958386 Africa/Johannesburg -27.17494 2014-10-01 968 08 0  S Sahara  DC8 Sahara FRM NC083 21.91872",
      "admin2": "DC8",
      "asciiname": "Sahara",
      "feature_code": "FRM",
      "admin3": "NC083",
      "longitude": "21.91872",
      "admin4": ""
    }
}
]

Note I'm only interested in display the data in the _source key. So the names of my columns are "elevation", "country", "geonameid", etc. And the cell data should be the values of those keys. My real dummy data actually has about 20 of these objects in the array, but i've just shown one for brevity.


Solution

  • Instead of only passing they key, may pass key and value:

     private createColumns(columnDatas) {
        return Object.entries(columnDatas[0]["_source"]).map(this.createColumn);
     }
    

    Now you can get it like this:

    private createColumn([key, value]) {
      //...
    }