0

Beware, I'm all new to ReactJS and PrimeReact. I'm trying to build a page that shows a list of persons, data drawn from another, Java backend server.

First off, here's the JSON data:

enter image description here

Here's my index.js:

import React from 'react';
import ReactDOM from 'react-dom';
import PersonManager from './PersonManager';
import './index.css';

ReactDOM.render(<PersonManager />, document.getElementById('root'));

As you can see, I'm calling PersonManager.js to display the actual content:

import React, { Component } from 'react';

import { DataTable } from 'primereact/datatable';
import { Column } from 'primereact/column';

import 'primereact/resources/themes/nova/theme.css';
import 'primereact/resources/primereact.min.css';
import 'primeicons/primeicons.css';

class PersonManager extends Component
{
    _entities = []

    get entities()
    {
        return this._entities;
    }

    set entities(entities)
    {
        this._entities = entities;
    }

    setEntities(entities)
    {
        this._entities = entities;
    }

    componentDidMount()
    {
        const url = 'http://localhost:8080/bbstats/ws/person/findall';
        
        fetch(url)
            .then(response => response.json())
            .then(data =>
            {
                // this._entities = data;
                // this.setEntities(data);
                this.setEntities(data);
                console.log('This is your data', data);
            })
            .catch(console.log)
    }

    render()
    {
        return (
            <div style={{ maxWidth: 1440, marginLeft: "auto", marginRight: "auto" }}>
                <DataTable value={this._entities}>
                    <Column field='id' header='ID' />
                    <Column field='lastName' header='Last Name' />
                    <Column field='firstName' header='First Name' />
                    <Column field='incognito' header='Incognito' />
                </DataTable>
            </div>
        );
    }
}


export default PersonManager;

However, the PrimeReact datatable stays empty.

In my browser (FF) it looks like the following:

enter image description here

I'm all new to this ReactJS / PrimeReact stuff and I have no idea why this doesn't display correctly.

I tried the same with data constructed in the component itself, which shows multiple rows (see sources below).

QUESTION:

What am I doing wrong?

Note, that the console correctly prints the data fetched from the other server. ‍♂️

-> PS: you can inspect the full code here: https://github.com/kawoolutions/basketball-stats-primereact/

Kawu
  • 13,647
  • 34
  • 123
  • 195
  • The way you set up your class makes sense, but it's more of a java way to do things than a react way (in this instance at least). I recommend you to instead add `entities` to the state and update this state with `this.setState` (https://reactjs.org/docs/state-and-lifecycle.html#adding-lifecycle-methods-to-a-class). If you pass part of the state and the state is changed your component will rerender and reflect the changes to your state. – 5eb Sep 06 '20 at 09:23
  • Hmm. I tried using the state var before, but this didn't have any effect. I will retry and maybe update the code example. – Kawu Sep 06 '20 at 09:33
  • I changed the code to the above. Still no datatable rows displayed. Please confirm if this is the React-ish way to do things. – Kawu Sep 06 '20 at 09:45
  • I haven't tried your code out yet, but one problem with this is that you're still passing `this._entities`. Instead you should pass `this.state.entities`. – 5eb Sep 06 '20 at 09:53
  • So true. You are my hero for this weekend. It works now. React is still a little creepy to me. Please post something as an answer so I can accept it. – Kawu Sep 06 '20 at 09:58
  • 1
    Rolled back for good. Thanks for helping. – Kawu Sep 06 '20 at 10:34

1 Answers1

1

You can try something like this:

class PersonManager extends Component {
  constructor(props) {
    super(props);

    this.state = {entities: []};
  }

  componentDidMount() {
    const url = 'http://localhost:8080/bbstats/ws/person/findall';

    fetch(url)
      .then((response) => response.json())
      .then((data) => {
        this.setState({entities: data});
      })
      .catch(console.log);
  }

  render() {
    return (
      <div style={{maxWidth: 1440, marginLeft: 'auto', marginRight: 'auto'}}>
        <DataTable value={this.state.entities}>
          <Column field="id" header="ID" />
          <Column field="lastName" header="Last Name" />
          <Column field="firstName" header="First Name" />
          <Column field="incognito" header="Incognito" />
        </DataTable>
      </div>
    );
  }
}

export default PersonManager;

So we can save entities in the state of the PersonManager component with an initial value. Since the constructor runs before the component mounts and renders we can safely access this.state.entities inside render.

In class-based components we can then update parts of the state (entities in this case) with a this.setState call which re-renders the component. This way the component correctly reflects the current state of the component.

5eb
  • 14,798
  • 5
  • 21
  • 65