No rows rendered, no errors detected - reactjs

In my React component, trying to generate rows from the state. State object is being populated, but no rows is being rendered:
class DataTable extends React.Component {
constructor(props) {
super(props);
this.renderTableData = this.renderTableData.bind(this);
this.fetchData = this.fetchData.bind(this);
this.state = {
Houses: []
};
}
componentDidMount() {
this.fetchData();
}
renderTableData() {
return( this.state.Houses.map((house, index) => {
<tr key={index}>
<td>{house.Id}</td>
<td>{house.Country}</td>
<td>{house.Address}</td>
<td>{house.Description}</td>
<td>{house.Photo}</td>
<td>{house.Price}</td>
</tr>
}))
}
fetchData = () => {
fetch('./AllHouses')
.then(rsp => rsp.json())
.then(allHouses => {
this.setState({ Houses: allHouses });
}).catch(
function (error) { console.log(error.message); }
);
console.log(this.state.Houses);
}
render() {
return (
<table>
<thead>
<tr>
<th>ID</th>
<th>Country</th>
<th>Address</th>
<th>Description</th>
<th>Photo</th>
<th>Price</th>
</tr>
</thead>
<tbody>
**{this.renderTableData() }**
</tbody>
</table>
);
}
}
ReactDOM.render(<DataTable />, document.getElementById('content'));

add return before <tr key={index}> OR wrap the tr with () instead of {}.
renderTableData() {
return this.state.Houses.map((house, index) => {
return <tr key={index}>
<td>{house.Id}</td>
<td>{house.Country}</td>
<td>{house.Address}</td>
<td>{house.Description}</td>
<td>{house.Photo}</td>
<td>{house.Price}</td>
</tr>
})
}

you could use the bind function but I recommend you use arrow functions directly.
You could call the array state.Houses on the jsx directly executing the map if you want, and then call the function renderTableData just like this:
import React, { Component } from 'react';
class StackOverflow extends Component {
state = {
Houses: [],
};
componentDidMount() {
// Data example
this.setState({
Houses: [
{
id: 1,
Country: 'Country 1',
Address: 'address 1',
Description: 'Description 1',
Photo: 'Photo 1',
Price: 'Price 1',
},
{
id: 2,
Country: 'Country 2',
Address: 'address 2',
Description: 'Description 2',
Photo: 'Photo 2',
Price: 'Price 2',
},
{
id: 3,
Country: 'Country 3',
Address: 'address 3',
Description: 'Description 3',
Photo: 'Photo 3',
Price: 'Price 3',
},
],
});
}
renderTableData(house, index) {
return (
<tr key={index}>
<td>{house.id}</td>
<td>{house.Country}</td>
<td>{house.Address}</td>
<td>{house.Description}</td>
<td>{house.Photo}</td>
<td>{house.Price}</td>
</tr>
);
}
render() {
return (
<table>
<thead>
<tr>
<th>ID</th>
<th>Country</th>
<th>Address</th>
<th>Description</th>
<th>Photo</th>
<th>Price</th>
</tr>
</thead>
<tbody>
{this.state.Houses.map((house, index) =>
this.renderTableData(house, index)
)}
</tbody>
</table>
);
}
}
export default StackOverflow;
it's much better organized because only you have HTML code in the renderTableData, after if you want you can export that <tr .... /tr> on a different component and call it on that function.
It's going to be cleaner and reusable your code.
Regards

Related

How to convert array to json and bind the json data in a table in react js

I have an array of,
I am trying to convert that to a JSON , so I can bind the data in a bootstrap table like this,
import "bootstrap/dist/css/bootstrap.min.css";
import Table from "react-bootstrap/Table";
function Home() {
const customers = [
{
CustomerId: 1,
Name: "John Hammond",
Country: "United States",
},
{
CustomerId: 2,
Name: "Mudassar Khan",
Country: "India",
},
{
CustomerId: 3,
Name: "Suzanne Mathews",
Country: "France",
},
{
CustomerId: 4,
Name: "Robert Schidner",
Country: "Russia",
},
];
return (
<div className="container">
<div className="row">
<div className="col-12">
<Table striped bordered hover size="sm">
<thead>
<tr>
<th>File Name</th>
<th>Username</th>
</tr>
</thead>
<tbody>
{customers.map(customers=>
<tr>
<td>{customers.Name}</td>
<td>{customers.Country}</td>
</tr>
)}
</tbody>
</Table>
</div>
</div>
</div>
);
}
export default Home;
Like in this example, they are binding Name and country from customers, I want to bind path data and mode data from the array and bind to the table.
I tried JSON.stringify but it is not working. How to do this?
This is the full code
import "bootstrap/dist/css/bootstrap.min.css";
import Table from "react-bootstrap/Table";
import { Octokit } from "octokit";
function Home() {
getContents();
let jsonString = '';
const customers = [
{
CustomerId: 1,
Name: "John Hammond",
Country: "United States",
},
{
CustomerId: 2,
Name: "Mudassar Khan",
Country: "India",
},
{
CustomerId: 3,
Name: "Suzanne Mathews",
Country: "France",
},
{
CustomerId: 4,
Name: "Robert Schidner",
Country: "Russia",
},
];
let contentResponse = "";
let valueArray = [];
async function getContents() {
try {
return await new Promise(async (resolve, reject) => {
try {
const octokit = new Octokit({
auth: "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",
});
const response = await octokit.request(
"GET /repos/KaranS0406/React/git/trees/4c1289a6405a5d87de6f1071ce723ee8b94be276?recursive=1"
);
console.log(response.data.tree);
contentResponse = response.data.tree;
Object.entries(contentResponse).forEach((element) => {
const [key, value] = element;
valueArray.push(value);
});
resolve("success");
} catch (error) {
reject("error");
}
});
} catch (error) {
console.log(error);
}
}
return (
<div className="container">
<div className="row">
<div className="col-12">
<Table striped bordered hover size="sm">
<thead>
<tr>
<th>File Name</th>
<th>Username</th>
</tr>
</thead>
<tbody>
{customers.map(customers=>
<tr>
<td>{customers.Name}</td>
<td>{customers.Country}</td>
</tr>
)}
</tbody>
</Table>
</div>
</div>
</div>
);
}
export default Home;
Add this after contentResponse line and check with console.log if is that what do you want.?
const convertdata = contentResponse.map((item) =>{
let obj={
Name:item.path,
Country:item.mode
}
})
Judging by what you get in the console, you already have what you need, just replace customers with your array (response.data.tree) and replace also name and country with path and mode.
{myArray.map(element =>
<tr>
<td>{element.path}</td>
<td>{element.mode}</td>
</tr>
)}

ReactJS - Adding value on specific table row

I created a react js app and have a table and it contains a button "Add Available Day" when I click it checkbox with days will show and when I choose a day it will automatically put in the table, however instead of updating specific row, changes are applied in all row. What I want to happen is for example I click add available day in first row then first row data must be updated not second and third row
This is my code:
import React from 'react';
import { Table, Button } from 'react-bootstrap';
const personData = [
{ id: 1, firstName: 'test1', lastName: 'test', day: [] },
{ id: 2, firstName: 'Jane', lastName: 'Doe', day: [] },
{ id: 3, firstName: 'John', lastName: 'Doe', day: [] },
{ id: 4, firstName: 'Clint', lastName: 'test', day: [] }
]
export default class App extends React.Component {
constructor() {
super();
this.state = {
day: [],
isSelectDay: false,
person: personData
}
}
handleSelectDay = (event) => {
let dayArr = [...this.state.day]
const value = event.target.value
const index = dayArr.findIndex(day => day === value);
if (index > -1) {
dayArr = [...dayArr.slice(0, index), ...dayArr.slice(index + 1)]
} else {
dayArr.push(value)
}
this.setState({ day: dayArr });
}
handleAddDay = () => {
this.setState({ isSelectDay: true })
}
render() {
const { isSelectDay, day } = this.state
const dayOptions = ["Monday, ", "Tuesday, ", "Wednesday", "Thursday, ", "Friday"].map((cur, ind) => {
return (
<div key={ind} className="checks" >
<label>
<input type="checkbox" name={cur} value={cur}
onChange={this.handleSelectDay} />{cur}
</label>
</div>
)
})
return (
<>
<Table striped bordered hover>
<thead>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Days Available</th>
</tr>
</thead>
<tbody>
{this.state.person.length > 0 ? (
this.state.person.map((person) => (
<tr key={person.id}>
<td>{person.firstName}</td>
<td>{person.lastName}</td>
<td>{day}<Button variant="success" onClick={this.handleAddDay}>Add Available Day</Button></td>
</tr>
))
) : (
<tr>
<td colSpan={3}>No Data</td>
</tr>
)}
</tbody>
</Table>
<div style={{ display: isSelectDay ? 'block' : 'none' }}>
{dayOptions}
</div>
</>
)
}
}
Is this something you're after?
Demo
Full Code
I changed isSelectDay to personSelected so when you click 'Add Available Day' it'll switch to the correct person object from personData. I then used this to update the people object in the state (a copy of personData) to add/remove days from day array. The day array was then used to output the days.
import React from "react";
import { Table, Button } from "react-bootstrap";
var personData = [
{ id: 1, firstName: "test1", lastName: "test", day: [] },
{ id: 2, firstName: "Jane", lastName: "Doe", day: [] },
{ id: 3, firstName: "John", lastName: "Doe", day: [] },
{ id: 4, firstName: "Clint", lastName: "test", day: [] }
];
export default class App extends React.Component {
constructor() {
super();
this.state = {
personSelected: null,
people: personData
};
}
handleSelectDay = (event) => {
let dayArr = [...this.state.personSelected.day];
const value = event.target.value;
const index = dayArr.findIndex((day) => day === value);
if (index > -1) {
dayArr = [...dayArr.slice(0, index), ...dayArr.slice(index + 1)];
} else {
dayArr.push(value);
}
let newPeople = this.state.people;
newPeople.find((x) => x === this.state.personSelected).day = dayArr;
this.setState({ people: newPeople });
};
handleAddDay = (person) => {
this.setState({ personSelected: person });
document
.querySelectorAll("input[type=checkbox]")
.forEach((el) => (el.checked = false));
};
render() {
const { personSelected } = this.state;
const dayOptions = [
"Monday, ",
"Tuesday, ",
"Wednesday",
"Thursday, ",
"Friday"
].map((cur, ind) => {
return (
<div key={ind} className="checks">
<label>
<input
type="checkbox"
name={cur}
value={cur}
onChange={this.handleSelectDay}
/>
{cur}
</label>
</div>
);
});
return (
<>
<Table striped bordered hover>
<thead>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Days Available</th>
</tr>
</thead>
<tbody>
{this.state.people.length > 0 ? (
this.state.people.map((person) => (
<tr key={person.id}>
<td>{person.firstName}</td>
<td>{person.lastName}</td>
<td>
{person.day}
<Button
variant="success"
onClick={() => this.handleAddDay(person)}
>
Add Available Day
</Button>
</td>
</tr>
))
) : (
<tr>
<td colSpan={3}>No Data</td>
</tr>
)}
</tbody>
</Table>
{personSelected !== null && (
<div style={{ display: "block" }}>{dayOptions}</div>
)}
</>
);
}
}

How make table row clickable?

import React from 'react'
import './myform.css'
const Emp=()=>{
const players=[
{
id: 1,
fullName: 'Employee 1',
email:'example1#mail.com',
joiningdate: '05/08/2020',
},
{
id: 2,
fullName: 'Employee 2',
email:'example2#mail.com',
},
{
id: 3,
fullName: 'Employee 3',
email:'example3#mail.com',
joiningdate: '10/08/2020'
},
{
id: 4,
fullName: 'Employee 4',
email:'example4#mail.com',
joiningdate: '05/08/2020'
},
]
/* I want to make row clickable and when it clicked information
from whole row is display on other page
I trying so much to make row clickable but it fails,
I got error "rowSelect() is undefined!!!" */
rowSelect=(event)=>{
console.log(event);
}
const renderPlayer=(player, index)=>{
return(
<tr key={index} onClick={this.rowSelect}>
<td>{player.id}</td>
<td>{player.fullName}</td>
<td>{player.email}</td>
<td>{player.joiningdate}</td>
</tr>
)
}
> //return data into table format on UI
return(
<div className='emp'>
<table className='border'>
<thead>
<tr >
<th>Id</th>
<th>Full Name</th>
<th>Email</th>
<th>Joining Date</th>
</tr>
</thead>
<tbody>
{players.map(renderPlayer)}
</tbody>
</table>
</div>
)
}
export default Emp
Since this is a functional component you need to declare your function as
function rowSelect(event) {
}
or
const rowSelect = event => {
}
then call it in your onClick like this
<tr key={index} onClick={rowSelect}>

React collapse row onClick

I have data that I need to show in table, for all rows I would like to use collapse function. Now I have working code that is collapsing all rows on click, but in what way I can collapse only one already clicked?
This is my code:
class Data extends React.Component {
constructor(props) {
super(props);
this.state = {
datas: [
{name: "or1", status: 11},
{name: "or3", status: 2},
{name: "or2", status: 22},
],
expanded: [],
isOpen: true,
};
}
toogleContent(openIs) {
this.setState({
isOpen: !openIs
})
}
render() {
return (
<Table responsive>
<thead className="text-primary">
<tr>
<th>Name</th>
<th>Status</th>
</tr>
</thead>
<tbody>
{this.state.datas.map((data, i) => (
<tr id={i} onClick={this.toogleContent.bind(this, this.state.isOpen)}>
<td>{data.name}</td>
<td><Collapse isOpen={this.state.isOpen}>
{data.status}</Collapse>
</td>
</tr>
))}
</tbody>
</Table>
)
}
}
I used their indexes to find out if they are opened or not, but you can use their names too, or add at data object a key isOpened =>
state={
isOpenIndexes = []
}
toogleContent(index) {
// we check if already opened
this.state.isOpenIndexes.find(openedIndex => openedIndex ===index ) ?
this.setState({
isOpenIndexes: this.state.isOpenIndexes.filter(openedIndex => openedIndex!==index)
})
:
this.setState({
isOpenIndexes: isOpenIndexes.concat([index])
})
}
{datas.map((data, i) => (
<tr id={i} onClick={this.toogleContent.bind(this, i)} isOpened={this.state.isOpenIndexes.find(openedIndex => openedIndex ===i )}>
<td>{data.name}</td>
<td>{data.status}</td>
</tr>
))}

React won`t render array map function

Hello I am new with new with React js. We have to create a project for counting points for teams, there are 4 teams in total. Every team has 5 children in it. Now I created an array to have 5 counts with id. The 5 counters are meant for the children. You should be able to add points for every child. So it is possible to update it by id with buttons. I`m using React in laravel. Here is the code:
export default class Gryffindor extends Component {
constructor(props) {
super(props);
this.state = {
counters: []
};
this.fetchCounter = this.fetchCounter.bind(this);
}
fetchCounter(e) {
const counters = [
{ id: 1, amount: 0 },
{ id: 2, amount: 0 },
{ id: 3, amount: 0 },
{ id: 4, amount: 0 },
{ id: 5, amount: 0 }
];
this.setState({ counters });
}
render() {
return <CounterBody counters={this.state.counters} />;
}
}
const CounterBody = ({ counters }) => (
<table>
<thead>
<tr>
<th>Test</th>
<th>Test</th>
<th>Test</th>
</tr>
</thead>
<tbody>
{counters.map(counter => (
<tr key={counter.id}>
<td></td>
<td>{counter.amount}</td>
<td></td>
</tr>
))}
</tbody>
</table>
);
if (document.getElementById("Gryffindor")) {
ReactDOM.render(<Gryffindor />, document.getElementById("Gryffindor"));
}
I have no idea why it is not showing up. Can someone help me?
You are never calling fetchCounter. You could call it inside componentDidMount.
class Gryffindor extends React.Component {
constructor(props) {
super(props);
this.state = {
counters: []
};
this.fetchCounter = this.fetchCounter.bind(this);
}
componentDidMount() {
this.fetchCounter();
}
fetchCounter() {
const counters = [
{ id: 1, amount: 0 },
{ id: 2, amount: 0 },
{ id: 3, amount: 0 },
{ id: 4, amount: 0 },
{ id: 5, amount: 0 }
];
this.setState({ counters });
}
render() {
return <CounterBody counters={this.state.counters} />;
}
}
const CounterBody = ({ counters }) => (
<table>
<thead>
<tr>
<th>Test</th>
<th>Test</th>
<th>Test</th>
</tr>
</thead>
<tbody>
{counters.map(counter => (
<tr key={counter.id}>
<td />
<td>{counter.amount}</td>
<td />
</tr>
))}
</tbody>
</table>
);
ReactDOM.render(<Gryffindor />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>

Resources