I am trying to populate my table, i am calling my api and doing the following
const addressTd = addressesInfo.map(item => (
<TableRow>
<TableCell align="right">{item.officeName}</TableCell>
<TableCell align="right">{item.address1}</TableCell>
</TableRow>));
then within my return I do the following
<Table>
<TableHead>
<TableRow>
<TableCell>Office Name</TableCell>
<TableCell>Address Line 1</TableCell>
</TableRow>
</TableHead>
<TableBody>
<TableCell>{addressTd}</TableCell>
</TableBody>
</Table>
however this does not give the desired affect
How could i allow office street to actually render under address? Thankyou
You are actually rendering all rows inside a cell. Here's the fixed version:
const addressTrs = addressesInfo.map((item, i) =>
<TableRow key={i}>
<TableCell align="right">{item.officeName}</TableCell>
<TableCell align="right">{item.address1}</TableCell>
</TableRow>
);
<Table>
<TableHead>
<TableRow>
<TableCell>Office Name</TableCell>
<TableCell>Address Line 1</TableCell>
</TableRow>
</TableHead>
<TableBody>
{addressTrs}
</TableBody>
</Table>
Also it's mandatory to have an unique key if you have an array of elements.
Related
I am using material-ui table. I can map the items and display it already however, mapping the orders.items in the table will cause this error:
TypeError: Cannot read property 'map' of undefined
These are the codes:
const [orders, setOrders] = useState([]);
{orders.map((order) => (
<div key={order.id}>
<Typography variant="h6">Ship By:{order.id}</Typography>
<TableContainer>
<Table className={classes.table} aria-label="spanning table">
<TableHead>
<TableRow>
<TableCell align="center" colSpan={3}>
Details
</TableCell>
<TableCell align="right">Price</TableCell>
</TableRow>
<TableRow>
<TableCell>Desc</TableCell>
<TableCell align="right">Qty.</TableCell>
<TableCell align="right">Unit</TableCell>
<TableCell align="right">Sum</TableCell>
</TableRow>
</TableHead>
<div>
<-------------------This is where the error is----------->
<TableBody>
{orders &&
orders.items.map((item) => (
<TableRow key={item.documentID}>
<TableCell>{item.productName}</TableCell>
</TableRow>
))}
</TableBody>
<-------------------This is where the error is----------->
</div>
</Table>
</TableContainer>
</div>
this is the JSON object
[
{
id: "IYQss7JM8LS4lXHV6twn",
total: 130,
items: [
{
qty: 1,
productPrice: "130",
documentID: "y8PN1cUyIr1sBnyV3Iqj",
productName: "Item1",
},
],
displayName: "Jennie Jenn",
},
];
So at your first render, you will not have items in orders array because it is blank array so when it try to map on order.items it will give error.
To solve this try to use optional chaining like below:-
<TableBody>
{order &&
order.items?.map((item) => (
<TableRow key={item.documentID}>
<TableCell>{item.productName}</TableCell>
</TableRow>
))}
</TableBody>
I want to retrive all items from the database then display users on a table
Users should be displayed like this:
I can display just the current user and here is my code :
const API_URL = "http://localhost:8080/api/auth/";
class AuthService {
getCurrentUser() {
return JSON.parse(localStorage.getItem('user'));;
}
const currentUser = AuthService.getCurrentUser();
<TableBody>
{this.state.users.map(row => (
<TableRow key={row.id}>
<TableCell component="th" scope="row">
{currentUser.id}
</TableCell>
<TableCell align="right">{currentUser.username}</TableCell>
<TableCell align="right">{currentUser.email}</TableCell>
<TableCell align="right">{currentUser.roles}</TableCell>
</TableRow>
I am assuming that your data is already loaded and you need to pass that data into your react component. I'd recommend to stick to functional components nowadays, since via hooks you can write the same logic as in class based components.
function MyTableComponent(props) {
return (
<TableBody>
{props.users.map(user => (
<TableRow key={row.id}>
<TableCell component="th" scope="row">
{user.id}
</TableCell>
<TableCell align="right">{user.username}</TableCell>
<TableCell align="right">{user.email}</TableCell>
<TableCell align="right">{user.roles}</TableCell>
</TableRow>
)}
</TableBody>
)}
Then you can use that component in your template and pass the props like so:
<MyTableComponent users={myUsersArray} />
I have the following code, and I want to hide or show the TableCell based on if statement, how do I do that?
I am using MATERIAL-UI : https://material-ui.com/
<TableBody>
{Object.entries(servicesCode).map(([key, value]) => (
servicesValueTotal[key] = ((servicesValue[key] + servicesTaxe[key])),
<TableRow key={servicesCode[key]}>
<TableCell component="th" scope="row">
{key}
</TableCell>
<TableCell align="center" >{servicesCode[key]}</TableCell>
<TableCell align="center">{servicesValue[key]}</TableCell>
<TableCell align="center">{servicesTaxe[key]}</TableCell>
<TableCell align="center">{servicesValueTotal[key]}</TableCell>
<TableCell align="center">{servicesTec[key]}</TableCell>
<TableCell align="center">{servicesClient[key]}</TableCell>
<TableCell align="center">{servicesStatus[key]}</TableCell>
</TableRow>
))}
</TableBody>
let showTableCell = (true) ? true : false; // you can have a single line condition or multiple line condition using if and else here.
<TableBody>
{Object.entries(servicesCode).map(([key, value]) => (
servicesValueTotal[key] = ((servicesValue[key] + servicesTaxe[key])),
<TableRow key={servicesCode[key]}>
<TableCell component="th" scope="row">
{key}
</TableCell>
{showTableCell && <TableCell align="center" >{servicesCode[key]}</TableCell>}
// or you could also add condition here as well
{showTableCell ? <TableCell align="center">{servicesValue[key]}</TableCell> : "Some other data here"}
<TableCell align="center">{servicesTaxe[key]}</TableCell>
<TableCell align="center">{servicesValueTotal[key]}</TableCell>
<TableCell align="center">{servicesTec[key]}</TableCell>
<TableCell align="center">{servicesClient[key]}</TableCell>
<TableCell align="center">{servicesStatus[key]}</TableCell>
</TableRow>
))}
</TableBody>
Why not use the feature called conditional rendering?
{condition && <Component />},
for example {condition && <TableCell align="center" >{servicesCode[key]}</TableCell>}
Note: As You are using a table to display data, it should have fixed number of th tags - table headings, thus removing table cells completely might be a bad solution.
You could also leave the table cell empty based on conditon like
<TableCell align="center" >{condition && servicesCode[key]}</TableCell> or like <TableCell align="center" >{condition ? someVariable : "No data here"}</TableCell>
I have a custom component that allows for my dropdowns to be generated via the backend, however i need to somehow store the two dropdown values in state, currently i am setting contractType to a value of 10 to meet the conditions of my conditional below, however when selecting a second value which is not 10 state is not reset, how could i achieve a change between two separate state values?
my code
const [contractType, setContractType] = useState(10);
function handleChange(event) {
setContractType(oldValues => ({
...oldValues,
[event.target.name]: event.target.value,
}));
}
my component below
<Search
type="procurementType"
name="procurementType"
label="Procurement Type"
id="procurementTypeId"
onChange={handleChange}
value={contractType}
/>
finally my if statement relating to the decision
{contractType == 10 ? <div className={classes.tableWrapper}>
<Table className={classes.table}>
<TableHead>
<TableRow >
<TableCell>ID</TableCell>
<TableCell>Internal Ref</TableCell>
<TableCell>Title</TableCell>
<TableCell>Organisation</TableCell>
</TableRow>
</TableHead>
<TableBody>
{localContracts.map(row => (
<TableRow className={classes.tableRow}>
<TableCell className={classes.tableCell}>{row.id}</TableCell>
<TableCell>{row.internalRef}</TableCell>
<TableCell>{row.title}</TableCell>
<TableCell>{row.organisationId}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</div> : <Table className={classes.table}>
<TableHead>
<TableRow >
<TableCell>ID</TableCell>
<TableCell>Internal Ref</TableCell>
<TableCell>Title</TableCell>
<TableCell>Organisation</TableCell>
</TableRow>
</TableHead>
<TableBody>
{frameworkContracts.map(row => (
<TableRow className={classes.tableRow}>
<TableCell className={classes.tableCell}>{row.id}</TableCell>
<TableCell>{row.internalRef}</TableCell>
<TableCell>{row.title}</TableCell>
<TableCell>{row.organisationId}</TableCell>
</TableRow>
))}
</TableBody>
</Table>}
I know it is quite easy but I'm stuck with this:
I want to create a table which will have strictly two columns and each columns will have many rows. I know for sure that each column will have many rows. Also each column will have different number or rows:
<Table>
<TableHeader>
<TableRow>
<TableHeaderColumn>ID</TableHeaderColumn>
<TableHeaderColumn>Name</TableHeaderColumn>
<TableHeaderColumn>Status</TableHeaderColumn>
</TableRow>
</TableHeader>
<TableBody>
<TableRow>
<TableRowColumn>1</TableRowColumn>
<TableRowColumn>John Smith</TableRowColumn>
<TableRowColumn>Employed</TableRowColumn>
</TableRow>
<TableRow>
<TableRowColumn>2</TableRowColumn>
<TableRowColumn>Randal White</TableRowColumn>
<TableRowColumn>Unemployed</TableRowColumn>
</TableRow>
<TableRow>
<TableRowColumn>3</TableRowColumn>
<TableRowColumn>Stephanie Sanders</TableRowColumn>
<TableRowColumn>Employed</TableRowColumn>
</TableRow>
<TableRow>
<TableRowColumn>4</TableRowColumn>
<TableRowColumn>Steve Brown</TableRowColumn>
<TableRowColumn>Employed</TableRowColumn>
</TableRow>
<TableRow>
<TableRowColumn>5</TableRowColumn>
<TableRowColumn>Christopher Nolan</TableRowColumn>
<TableRowColumn>Unemployed</TableRowColumn>
</TableRow>
</TableBody>
</Table>
The material UI table components are these. Any ideas?
You could store the person data into an array an then map them into a new array of react components of them which then can be rendered:
[...]
let persons = [{
id: 1,
name: 'John Smith',
status: 'Employed'
}, [...] ];
let rows = persons.map(function(person){
return (
<TableRow>
<TableRowColumn>{person.id}</TableRowColumn>
<TableRowColumn>{person.name}</TableRowColumn>
<TableRowColumn>{person.status}</TableRowColumn>
</TableRow>
);
});
[...]
render() {
return (
<Table>
<TableHeader>
<TableRow>
<TableHeaderColumn>ID</TableHeaderColumn>
<TableHeaderColumn>Name</TableHeaderColumn>
<TableHeaderColumn>Status</TableHeaderColumn>
</TableRow>
</TableHeader>
<TableBody>
{rows}
</TableBody>
</Table>
);
[...]
I didn't test it, but maybe it helps you getting on the right track.