Unable to render async Django REST API response in React table - reactjs

import React , { Component } from 'react';
import axios from 'axios'
import ReactTable from "react-table-6";
import "react-table-6/react-table.css"
class Users extends Component {
constructor(props){
super(props)
this.state = ({
users: [],
loading: true,
})
}
async getUsersData(){
const res = await axios.get(`${process.env.REACT_APP_API_URL}/...`)
.then(res => {
console.log(res.data.data)
this.setState({
users: [res.data]
})
})
.catch(error => {
console.log(error)
})
}
componentDidMount(){
this.getUsersData()
}
render() {
const columns = [{
Header: 'ID',
accessor: 'id',
}
,{
Header: 'Password',
accessor: 'password' ,
}
,{
Header: 'Email',
accessor: 'email' ,
}
,{
Header: 'First Name',
accessor: 'first_name',
},
{
Header: 'Last Name',
accessor: 'last_name',
},
]
return (
<ReactTable
data={this.state.users}
columns={columns}
/>
);
}
}
export default Users;
This generates a response in the console, but does not populate the table.
What needs to be fixed to render the response in the React table

Related

Using an API to create data in a ReactTable

I'm new to React.js and want to use this API here: https://atlas.api.barclays/open-banking/v2.2/branches to create a table with Barclays branches data. My problem is, when I render the app, I can't seem to upload the data into the table, only the column's headers. Any help would be appreciated. Thanks!
import React, { Component } from 'react'
import axios from 'axios'
import ReactTable from "react-table-6";
import 'react-table-6/react-table.css';
export default class App extends Component {
constructor(props){
super(props)
this.state = {
branches: [],
loading:true
}
}
async getBranchesData(){
const data = await axios.get('https://atlas.api.barclays/open-banking/v2.2/branches')
console.log(data.Branch)
this.setState({loading:false, branches: data.Branch})
}
componentDidMount(){
this.getBranchesData()
}
render() {
const columns = [
{
Header: 'Identification',
accessor: 'Identification',
}
,{
Header: 'Sequence Number',
accessor: 'SequenceNumber' ,
}
,{
Header: 'Name',
accessor: 'Name' ,
}
,{
Header: 'Type',
accessor: 'Type',
}
,{
Header: 'Photo',
accessor: 'Photo',
}
,{
Header: 'Customer Segment',
accessor: 'CustomerSegment',
}
,{
Header: 'Service and Facility',
accessor: 'ServiceAndFacility',
}
,{
Header: 'Accessibility',
accessor: 'Accessibility',
}
,{
Header: 'Other Accessibility',
accessor: 'OtherAccessibility',
}
,{
Header: 'Other Service and Facility',
accessor: 'OtherServiceAndFacility',
}
,{
Header: 'Availability',
accessor: 'Availability',
}
,{
Header: 'Contact Info',
accessor: 'ContactInfo',
}
,{
Header: 'Postal Address',
accessor: 'PostalAddress',
}
]
return (
<ReactTable
data={this.state.branches}
columns={columns} />
)
}
} ```
change the next line:
this.setState({loading:false, branches: data.Branch})
for this:
this.setState({loading:false, branches: data.Brand.Branch})
The problem is in the way you're using the React Table library. It only provides table utilities and not a table component as you're trying to use. You can check this basic usage example in their docs to try to fit your use case.
You can use HTML table elements or any UI component libraries (such as Bootstrap or Material UI) to render your table, but it's up to you.
Look at the response of the api.
const response = {
meta: {},
data: [
{
"Brand": [
{
"BrandName": "Barclays UK",
"Branch": [
{
"Identification": "UK-B-20533008",
// etc
},
{
"Identification": "UK-B-20533008",
// etc
},
// etc
]
}
]
}
]
};
I think you want data.data[0].Brand[0].Branch.

Auto Refresh React Table upon success of the delete action server side

How can i refresh the react-table upon editing/deleting a data (server-side based), Here's my code so far
import React,{useState,useEffect} from 'react'
import { useTable, usePagination } from 'react-table'
// import {TableContainer} from './?'
import Table from './TableContainer'
import axios from 'axios';
// Let's add a fetchData method to our Table component that will be used to fetch
// new data when pagination state changes
// We can also add a loading state to let our table know it's loading new data
function App() {
const columns = React.useMemo(
() => [
{
Header: 'Name',
columns: [
{
Header: 'name',
accessor: 'name',
},
{
Header: 'Last Name',
accessor: 'lastName',
},
],
},
{
Header: 'Info',
columns: [
{
Header: 'Age',
accessor: 'age',
},
{
Header: 'Visits',
accessor: 'visits',
},
{
Header: 'Status',
accessor: 'status',
},
{
Header: 'Profile Progress',
accessor: 'progress',
},
{
Header: 'Action',
accessor: '',
id: 'edit',
accessor: 'id',
Cell: ({value}) => (<button onClick={() => editData(value)} data-id={value}>Edit</button>)
},
],
},
],
[]
)
// We'll start our table without any data
const [data, setData] = React.useState([])
const [loading, setLoading] = React.useState(false)
const [pageCount, setPageCount] = React.useState(0)
const [ totalPages, setTotalPages ] = useState(0);
const [ sizePerPage, setSizePerPage ] = useState(10);
const [ page, setPage ] = useState(0);
const [ filtered, setFiltered ] = useState("");
const fetchIdRef = React.useRef(0)
const fetchData = React.useCallback(({ pageSize, pageIndex,filtered }) => {
console.log(filtered);
setLoading(true);
axios.get(`http://127.0.0.1:8000/api/schools?q=${filtered}&sizePerPage=${pageSize}&page=${pageIndex+1}`)
.then((res)=> {
setData(res.data.data);
setSizePerPage(res.data.meta.per_page)
setPage(res.data.meta.current_page)
setPageCount(Math.ceil(res.data.meta.total / pageSize))
setLoading(false)
});
}, [])
function editData(name) {
setLoading(true);
console.log(name)
console.log(sizePerPage);
axios.delete(`http://127.0.0.1:8000/api/schools/${name}`)
.then((res) =>{
// fetchData(sizePerPage);
})
}
return (
<Table
columns={columns}
data={data}
fetchData={fetchData}
loading={loading}
pageCount={pageCount}
filtered={filtered}
filterable
/>
)
}
export default App
When I call the fetch data upon the response, it can't access the callback param of pageSize,pageIndex, filtered I've already try to call it with params but it gives me an error that the pageSize,pageIndex are now undefined
What am I doing wrong?

Making an API call through ReactJs, fetch JSON and display in ag-grid

EDIT:
I have experimented around the code. The modified code is given below.
Now I get an error "TypeError: rowData.forEach is not a function" in the browser.
When I console log, enter image description here it is showing the JSON arrays (I have attached a screenshot).
I think the problem is something to do with JSON object not getting converted to an array. Can someone experienced, please help?
MODIFIED CODE
import React, { Component } from 'react';
import { AgGridReact } from 'ag-grid-react';
import 'ag-grid-community/dist/styles/ag-grid.css';
import 'ag-grid-community/dist/styles/ag-theme-balham.css';
//import {Grid} from '#ag-grid-community/all-modules';
class App extends Component {
constructor (props)
{
super(props);
this.state={
isLoaded: true,
columnDefs: [{
headerName: "Id", field: "id"
}, {
headerName: "Name", field: "name"
}, {
headerName: "Description", field: "description"
}, {
headerName: "Price", field: "price"
},
{
headerName: "Firm Name", field: "category_id"
},
{
headerName: "Amount", field: "category_name"
}
],
rowData: []
};
}
componentDidMount()
{
console.log ("entered");
fetch("http://localhost/api/product/read.php")
.then (res => res.json() )
//.then ((result) => {this.setState({rowData: result, isLoaded: true})},
.then(rowData => this.setState({rowData}),
(error) => {
console.log("error");
this.setState({
isLoaded: false,
error
});
}
)
}
render() {
const {error,isLoaded,rowData } = this.state;
if (error) {
return <div>Error: {error.message}</div>;
}
else if (!isLoaded) {
return <div>Loading...</div>;
}
else {
console.log({rowData});
return (
<div
className="ag-theme-balham"
style={
{
height: '800px',
width: '1200px' }
}
>
<AgGridReact
columnDefs={this.state.columnDefs}
rowData={this.state.rowData}
>
</AgGridReact>
</div>
);
}
}
}
export default App;
I have been trying to call an API from reactjs.I have tried fetch,jquery and apiox codes but I am getting an error. I actually want to call an external URL from one of our other software but since it is not working, I have created a php file on localhost and tried calling that file.In each case it is printing "entered" and then "error" to console.
Both the external api file and the localhost file, when tried in the browser are returning JSON objects.
PLease see code below.
import React, { Component } from 'react';
import { AgGridReact } from 'ag-grid-react';
import 'ag-grid-community/dist/styles/ag-grid.css';
import 'ag-grid-community/dist/styles/ag-theme-balham.css';
class ListOrders extends Component {
constructor(props) {
super(props);
this.state = {
columnDefs: [{
headerName: "Invoice No", field: "id"
}, {
headerName: "Invoice Date", field: "name"
}, {
headerName: "Payer Name", field: "description"
}, {
headerNAme: "Ship To Name", field: "price"
},
{
headerNAme: "Firm Name", field: "category_id"
},
{
headerNAme: "Amount", field: "category_name"
}
],
rowData: []
};
}
componentDidMount()
{
console.log ("entered");
fetch("http://localhost/api/product/read.php",{
mode: "no-cors",
method: 'GET', // or 'PUT'
headers: {
'Content-Type': 'application/json',
},
// body: JSON.stringify(),
})
.then(response => response.json())
.then(
(response) => {
console.log("result");
this.setState( {
rowData: response.JSON
//console.log(rowData)
});
},
(error) => {
console.log("error");
this.setState({
isLoaded: true,
error
});
}
)
}
render()
{
return (
<div
className="ag-theme-balham"
style={
{
height: '800px',
width: '1200px' }
}
>
<AgGridReact
columnDefs={this.state.columnDefs}
rowData={this.state.rowData}>
</AgGridReact>
</div>
);
}
}
export default ListOrders ;

The column with audio file playback from the file system does not change on sorting or paging

I'm new in React and I'm trying to create a simple react table - a list of records with audio file playback. Metadata about records are from database and the audio file is loaded according to the file_address column from the file system.
During sorting and paging, all table columns change, except the playback column, which does not change in general. I attached my code. Thank you in advance for your help :)
import React from 'react';
import ReactTable from 'react-table'
import 'react-table/react-table.css'
import './App.css';
import { Container } from "#material-ui/core";
import { maxHeight } from '#material-ui/system';
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
isLoaded: false,
error: null,
items: []
};
}
/**
* call BE endpoint to receive records data
*/
componentDidMount() {
fetch("/records")
.then(res => res.json())
.then(
(result) => {
this.setState({
isLoaded: true,
items: result.Records
});
},
(error) => {
this.setState({
isLoaded: true,
error
});
}
)
}
/**play wav audio */
async play(file_address) {
var audio = new Audio({file_address});
audio.type = 'audio/wav';
try {
await audio.play();
console.log('Playing...');
} catch (err) {
console.log('Failed to play...' + err);
}
}
/**create table structure */
render(){
const items = this.state.items;
const columns = [{
Header: 'ID',
accessor: 'Id',
sortable: true
},
{
Header: 'Name',
accessor: 'Name',
sortable: true
},
{
id: 'Play',
Header: 'Play',
accessor: a => <audio controls>
<source src={a.File_Address} type="audio/wav" />
</audio>
},
{
Header: 'Duration',
accessor: 'Duration',
sortable: true
},
{
Header: 'Date',
accessor: 'Date',
sortable: true
},
{
Header: 'Time',
accessor: 'Time',
sortable: true
},{
Header: 'File address',
accessor: 'File_Address'
}
]
/**return react components with records data */
return (
<Container className="container" maxWidth="xl" style={{ height: maxHeight, background: '#ffffff', color: '#424242'}}>
<h1 className="title">Records</h1>
<ReactTable
style={{
background: '#eeeeee',
color: '#000000'
}}
data={items}
columns={columns}
/>
</Container>
)
}
}
export default App;

React table rendering in the form of a row

Kind of a React noobie here so please don't judge.
The react table is rendering in the form of a row.
My Component:
import React, { Component } from 'react';
import ReactTable from 'react-table';
// import 'react-table/react-table.css';
class Variants extends Component {
constructor(props) {
super(props);
}
render() {
const columns = [
{
Header: 'Gene',
accessor: 'gene'
},
{
Header: 'Nucleotide Change',
accessor: 'nucleotide_change'
},
{
Header: 'Protein Change',
accessor: 'protein_change'
},
{
Header: 'Other Mappings',
accessor: 'other_mappings'
},
{
Header: 'Alias',
accessor: 'alias'
},
{
Header: 'Transcripts',
accessor: 'transcripts'
},
{
Header: 'Region',
accessor: 'region'
},
{
Header: 'Reported Classification',
accessor: 'reported_classification'
},
{
Header: 'Inferred Classification',
accessor: 'inferred_classification'
},
{
Header: 'Source',
accessor: 'source'
},
{
Header: 'Last Evaluated',
accessor: 'last_evaluated'
},
{
Header: 'Last Updated',
accessor: 'last_updated'
},
{
Header: 'More Information',
accessor: 'url',
Cell: e => (
<a target="_blank" href={e.value}>
{' '}
{e.value}{' '}
</a>
)
},
{
Header: 'Submitter Comment',
accessor: 'submitter_comment'
}
];
if (this.props.variants && this.props.variants.length > 0) {
return (
<div>
<h2>
{' '}
There are {this.props.variants.length} variants of this gene!
</h2>
<div>
<ReactTable
data={this.props.variants}
columns={columns}
defaultPageSize={3}
pageSizeOptions={[3, 5, 10, 50, 100]}
/>
</div>
</div>
);
} else {
return [];
}
}
}
export default Variants;
It is rendering the whole table as a row for some weird reason. I have attached the image to show what is happening. Also, the pagination buttons are not nice. Can they be modified?
Has anyone come across a similar problem?
I got it working below. I simplified the data since you didn't provide an example data set but this should help you.
The only thing I can think you have wrong is either you need to uncomment import 'react-table/react-table.css'; or maybe you are passing in your props wrong in <Variants variants={variants}/>
Variants.js
import React, { Component } from 'react';
import ReactTable from 'react-table';
import 'react-table/react-table.css';
class Variants extends Component {
render() {
const columns = [
{
Header: 'Gene',
accessor: 'gene'
},
{
Header: 'Nucleotide Change',
accessor: 'nucleotide_change'
},
{
Header: 'Protein Change',
accessor: 'protein_change'
}
];
if (this.props.variants && this.props.variants.length > 0) {
return (
<div>
<h2>
{' '}
There are {this.props.variants.length} variants of this gene!
</h2>
<div>
<ReactTable
data={this.props.variants}
columns={columns}
defaultPageSize={3}
pageSizeOptions={[3, 5, 10, 50, 100]}
/>
</div>
</div>
);
} else {
return [];
}
}
}
export default Variants;
App.js
import React from 'react';
import './App.css';
import Variants from "./Variants";
const variants = [
{
gene:'a',
nucleotide_change:'a',
protein_change:'a'
},
{
gene:'b',
nucleotide_change:'b',
protein_change:'b'
}
];
function App() {
return (
<div className="App">
<Variants variants={variants}/>
</div>
);
}
export default App;

Resources