0

I'm trying to hit a REST API I've made and dump the returned data into a simple table using React.

I understand that I can hit my API and get the JSON data using this line:

 fetch('http://localhost:5000/api/v0.1/Organisations').then(r=>r.json());

If I add a .then(d=>console.log(d)); I get the data showing up in the log, so I know my API is successfully returning the data:

Data

However, when I launch the application, I'm getting Cannot convert undefined or null to object on the getKeys function of my component.

I'm assuming, this is because the promise returned by fetch hasn't been fulfilled yet but I don't know how to wait for it.

My component definition:

export default class Table extends React.Component
{

    constructor(props){
        super(props);
        this.getHeader = this.getHeader.bind(this);
        this.getRowsData = this.getRowsData.bind(this);
        this.getKeys = this.getKeys.bind(this);
    }

    getKeys = function(){
        return Object.keys(this.props.data[0]);
    }

    getHeader = function(){
        var keys = this.getKeys();
        return keys.map((k,i)=>{
            return <th key={k}>{k}</th>
        })
    }

    getRowsData = function(){
        var items = this.props.data;
        var keys = this.getKeys();
        return items.map((r,i)=>{
            return <tr key={i}><RenderRow key={i} data = {r} keys={{keys}}/></tr>
        })
    }

    render() {
        return (
            <div>
                <table>
                    <thead>
                    <tr>{this.getHeader()}</tr>
                    </thead>
                    <tbody>
                    {this.getRowsData()}
                    </tbody>
                </table>
            </div>

        );
    }
}
const RenderRow = (props) =>{
    return props.keys.map((k,i) => {
        return <td key={props.data[k]}>{props.data[k]}</td>
    })
}

And my app.js:

import './App.css';
import './components.js'
import React from 'react';
import Table from "./components";




function App() {
    var data = fetch('http://localhost:5000/api/v0.1/Organisations').then(r=>r.json());
    fetch('http://localhost:5000/api/v0.1/Organisations').then(r=>r.json()).then(d=>console.log(d));
  return (
    <div className="App">
      <header className="App-header">
        <h1>Vaultex Tech Test</h1>
        <h2>Organisations</h2>
        <Table data={data}/>

      </header>
    </div>
  );
}

export default App;

I'm new to React, usually work on the back-end, so if I'm missing some sort of fundamental concept pointing that out would be pretty helpful.

1 Answer 1

2

You should probably add some statehandling for fetching stuff async. Example:

import {useState, useEffect} from 'react';

//Adding a state placeholder for your result
const [myData, setMyData] = useState();
//Adding a loading state
const [loading, setLoading] = useState(true);

//Add an async load function that resolves your endpoint
const load = async () => {
  setLoading(true);
  const data = await fetch('http://localhost:5000/api/v0.1/Organisations');

  setMyData(data.json());
  setLoading(false);
}

useEffect(() => {
  //this will trigger your load function once when the component is mounted
  load();
}, []);

if (loading) return <div>Loading...</div>;

return <Table data={myData} />;
Sign up to request clarification or add additional context in comments.

1 Comment

Yes, state handling is the way to go. Thsorens was faster with the answer. I'd like to leave the demo here to see fetching in action.

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.