Text nodes cannot appear as a child of <tbody> - javascript

My code is really simple and I checked everything but this is getting this error repeatedly. Please suggest to me what can i change. I tried using but that dint work.I even checked other answers but they dint work.
import React from "react";
import { Button, Table } from "react-bootstrap";
import "bootstrap/dist/css/bootstrap.min.css";
import Employees from "./Employees";
const Home = () => {
return (
<>
<div>
<Table>
<thead>
<tr>
<th>Name</th>
<th>Age</th>
</tr>
</thead>
<tbody>
{Employees && Employees > 0 ? Employees.map((item) => {
return (
<tr key={item.id}>
<td>{item.name}</td>
<td>{item.age}</td>
</tr>
);
})
: "No data available"}
</tbody>
</Table>
</div>
</>
);
};
export default Home;

If there is no data your table would look like
<table>
<tbody>
No data available
</tbody>
</table>
It needs to have a <tr> and a <td>

Related

Create a link to a user ID in a table

I have a simple table and I want to navigate to the user.id but it throws off the formatting. Is there another way to do this or do I move LinkToUser?
I have removed all styling so there is nothing conflicting.
import styled from 'styled-components'
import { Link } from 'react-router-dom'
export const LinkToUser = styled(Link)`
`
export const StyledTable = styled.table`
`;
export const THead = styled.thead`
`;
export const TR = styled.tr`
`;
export const TBody = styled.tbody`
`;
export const TH = styled.th`
`;
export const TD = styled.td`
`;
<StyledTable>
<THead>
<TR>
<TH>{copy.tableHeaderA}</TH>
<TH>{copy.tableHeaderB}</TH>
<TH>{copy.tableHeaderC}</TH>
</TR>
</THead>
<TBody>
{fetchedUsersData?.map((user: Users) => (
<LinkToUser to={`/users/${user.id}`}>
<TR key={user.id}>
<TD>
<p>{user.username}</p>
</TD>
<TD>
<p>{user.name}</p>
</TD>
<TD>
<p>{user.company.name}</p>
</TD>
</TR>
</LinkToUser>
))}
</TBody>
</StyledTable >
Use onClick and history if you are using react-router-dom
<StyledTable>
<THead>
<TR>
<TH>{copy.tableHeaderA}</TH>
<TH>{copy.tableHeaderB}</TH>
<TH>{copy.tableHeaderC}</TH>
</TR>
</THead>
<TBody>
{fetchedUsersData?.map((user: Users) => (
<TR key={user.id}
onClick={()=>{
history.push(`/users/${user.id}`)
}
>
<TD>
<p>{user.username}</p>
</TD>
<TD>
<p>{user.name}</p>
</TD>
<TD>
<p>{user.company.name}</p>
</TD>
</TR>
))}
</TBody>
</StyledTable >
You have to move key to the parent component inside map function like this,
from:
{fetchedUsersData?.map((user: Users) => (
<LinkToUser to={`/users/${user.id}`}>
<TR key={user.id}>
to:
{fetchedUsersData?.map((user: Users) => (
<LinkToUser to={`/users/${user.id}`} key={user.id}>
<TR >
Also make sure this table is inside router parent tree.
Another problem might be to not be able to have Link as direct child of TableBody, in that case i suggest to move your link inside one of the TD elements

Iterating over a series of objects and inserting then into a Bootstrap table

All in all trying to loop over a jsonplaceholder's (/users) name, username, and email. Im getting the data with the help of axios and im displaying it through react. I have two seperate files: App.js (the one that comes with react) and AlbumList.js
In App.js:
import React, { Component } from 'react'
import './App.css';
import AlbumList from './Components/AlbumList';
class App extends Component {
render() {
return (
<div className="App">
<AlbumList/>
</div>
)
}
}
export default App
And in Album.List
import axios from 'axios';
import React from 'react';
export default class AlbumList extends React.Component {
state = {
persons: [],
};
componentDidMount() {
axios.get('https://jsonplaceholder.typicode.com/users').then(res => {
console.log(res);
this.setState({ persons: res.data });
});
}
render() {
return (
<div>
<table class="table">
<caption>List of users</caption>
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">name</th>
<th scope="col">username</th>
<th scope="col">e-mail</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row"></th>
<td>Mark</td>
<td>Otto</td>
<td>#mdo</td>
</tr>
</tbody>
</table>
{/* { this.state.persons.map(person => <div>{person.name} | {person.username} | {person.email}</div> )} */}
</div>
)
}
}
The table im using is the one that bootstrap offers, the default one. How do I do this? thanks
You need to map the data you got from your fetch request to the "tbody" tag, here you are just mapping the result in a div.
Check below your code with the modification needed:
render() {
return (
<div>
<table class="table">
<caption>List of users</caption>
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">name</th>
<th scope="col">username</th>
<th scope="col">e-mail</th>
</tr>
</thead>
<tbody>
{ this.state.persons.map(person =>
<tr>
<th scope="row"></th>
<td>{person.name}</td>
<td>{person.username}</td>
<td>{person.email}</td>
</tr> )}
</tbody>
</table>
</div>
)
}
Edit: typo

How to make each row of the table clickable in React?

There are quite a few answers that I found but none of them seem to work for my scenario.
I want to make each row clickable and log it on the console. How can I achieve this?
My React code is as follows:
class ConsumerList extends Component {
handleClick = building => {
console.log(building);
};
render() {
return (
<div className="table-responsive table-hover">
<table className="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Name</th>
<th scope="col">Farm</th>
<th scope="col">Cost</th>
<th scope="col">Change</th>
</tr>
</thead>
<tbody>
{this.props.buildings.map(building => (
<tr key={building.id} onClick={() => this.handleClick(building)}>
<th scope="row">{building.id}</th>
<td>{building.name}</td>
<td>{building.farmName}</td>
<td>{building.cost}</td>
<td className="text-success">
<FontAwesomeIcon icon={faArrowDown} />
{building.change}
</td>
</tr>
))}
</tbody>
</table>
</div>
);
}
}
export default ConsumerList;
onClick={(building) => this.handleClick(building)} modify this in your code while adding the listener. You will get the log into the console.
You need a routing setup.Use the withRouter high order component, and wrap that to the component that will push to history so that you get access to the history object, to perform various routing operations.
Check out the official documentation for more info
import React from "react";
import { withRouter } from "react-router-dom";
class ConsumerList extends React.Component {
handleClick = building => {
console.log(building);
this.props.history.push("/some/Path"); //path you want to redirect to
};
render() {
return (
<div className="table-responsive table-hover">
<table className="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Name</th>
<th scope="col">Farm</th>
<th scope="col">Cost</th>
<th scope="col">Change</th>
</tr>
</thead>
<tbody>
{this.props.buildings.map(building => (
<tr key={building.id} onClick={(building) => this.handleClick(building)}>
<th scope="row">{building.id}</th>
<td>{building.name}</td>
<td>{building.farmName}</td>
<td>{building.cost}</td>
<td className="text-success">
<FontAwesomeIcon icon={faArrowDown} />
{building.change}
</td>
</tr>
))}
</tbody>
</table>
</div>
);
}
}
export default withRouter(MyComponent);

How can i display key value pairs in a table grid in react js.?

I'm trying to display key-value pairs in react js,
but somehow I cannot display them properly. I have created a table widget and I am not getting the right display
My table Widget
import React from "react";
function Table(props) {
const { tablevalue } = props;
console.log(tablevalue);
return (
<div className="table">
<table className="table table-hover">
<tbody>
{tablevalue.map((item, value) =>
Object.entries(item, (key, value) => {
return (
<tr className="table-row">
<th scope="col" key={`tablevalue-${key}`}>
{key}
</th>
<td key={`tablevalue-${value}`}>{value}</td>
</tr>
);
})
)}
</tbody>
</table>
</div>
);
}
export default Table;
app.js
import React, { Fragment } from "react";
import Dropdown from './components/widgets/Dropdown/index'
import Table from './components/widgets/Table/index'
function DropdownTest() {
return (
<h3>
<b>Profit</b>
</h3>
<br />
<Table
tablevalue = {[{key:'Binance' , value: 'Polonix'}, {key:'Profit' , value:'Loss'}]}
/>
</div>
);
}
export default DropdownTest;
My output
Whereas I want my output to be displayed in terms of table
You can use table header
<tbody>
<tr>
<th>Key</th>
<th>Value</th>
</tr>
{tablevalue.map(({ key, value }) => (
<tr className="table-row">
<td key={`tablevalue-${key}`}>{key}</td>
<td key={`tablevalue-${value}`}>{value}</td>
</tr>
))}
</tbody>
Code
const Table = ({ tablevalue }) => (
<div className="table">
<table className="table table-hover">
<tbody>
<tr>
<th>Key</th>
<th>Value</th>
</tr>
{tablevalue.map(({ key, value }) => (
<tr className="table-row">
<td key={`tablevalue-${key}`}>{key}</td>
<td key={`tablevalue-${value}`}>{value}</td>
</tr>
))}
</tbody>
</table>
</div>
);
const DropdownTest = () => (
<div>
<h3>
<b>Profit</b>
</h3>
<br />
<Table
tablevalue={[
{ key: "Binance", value: "Polonix" },
{ key: "Profit", value: "Loss" }
]}
/>
</div>
);
ReactDOM.render(
<React.StrictMode>
<DropdownTest />
</React.StrictMode>,
document.getElementById("root")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>
I've not seen Object.entries used this way. I would usually use a forEach on it:
Object.entries(item).forEach(entry => {
let key = entry[0];
let value = entry[1];
});
Though a little bit more performant would be using a for in instead, as Object.entries creates a brand new array then forEach iterates through that, which is unnecessary:
for (const key in item) {
let value = obj[key];
}
You can do it this way:
import React from "react";
export default props => {
console.log(props.tablevalue);
const ths = props.tablevalue.map(({ key, value }) => (
<th key={value}>{key}</th>
));
const values = props.tablevalue.map(obj => <td>{obj.value}</td>);
return (
<>
<table>
<tr>{ths}</tr>
<tr>{values}</tr>
</table>
</>
);
};
Here's a stackblitz that displays the table.
Ultimately it all comes down to how you want that table to be displayed, you can tweak some things as you want.
I think you have to create a header separately. and after that loop thought the data and apply css for table row. please find the below code.
import React from 'react';
import './index.css';
function Table(props) {
const {
tablevalue,
} = props
console.log(tablevalue)
return (
<div className="table">
<table className="table table-hover">
<tbody>
<tr>
<th>Key</th>
<th>Value</th>
</tr>
{tablevalue.map((item, value) => {
return (
<tr className="table-row">
<td key={`tablevalue-${value}`}>{item.key}</td>
<td key={`tablevalue-${value}`}>{item.value}</td>
</tr>
)
})}
</tbody>
</table>
</div>
)
}
export default Table;
Check this sandbox: https://codesandbox.io/s/goofy-breeze-fdcdr
Object.keys(tablevalue[0]).map((key) => {key}). You can use this in header tr and loop over it then
Change the Table component to something like this:
import React from "react";
function Table(props) {
const { tablevalue } = props;
return (
<div className="table">
<table className="table table-hover">
<tbody>
<tr>
{Object.keys(tablevalue[0]).map(key => (
<th key={key}>{key}</th>
))}
</tr>
{tablevalue.map(({ key, value }) => (
<tr className="table-row" key={`tablevalue-${key}`}>
<td>{key}</td>
<td>{value}</td>
</tr>
))}
</tbody>
</table>
</div>
);
}
export default Table;

React display props on table from props.object

I have a component in react where I pass so data in a prop:
<Mycomponent names={[{name: 'peter'},{name: 'pan'}]} />
Then I have a component which has a table and where I want to display the data in a
Here is the component
import React from 'react';
const Mycomponent = (props) => <div>
<table>
<thead>
<tr>
<th>Name</th>
</tr>
</thead>
<tbody>
<tr>
<td>{ props.names }</td>
</tr>
</tbody>
</table>
</div>;
export default Mycomponent;
How do I loop and display each name in a <tr><td>{props.names.name}</td></tr> ?
<tbody>
{
props.names.map( ({name}, i) => <tr key={i}><td>{ name }</td></tr> )
}
</tbody>
will iterate over all of props.names and return a tr for each

Categories

Resources