Trying to display key of object in array to table - javascript

this feels like a super simple question I thought I knew the solution but just can't figure out why it's not working.
I am trying to display records from Firestore in a table.
Some of the fields go in fine into the table, but one of the fields which is made up of an
array of objects is giving me problems, the object contains childName, childAge & childId. I am trying to display childName.
I just want to display the child name of the first Children object.
but I keep getting the error:
"TypeError: Cannot read property '0' of undefined"
<TableBody>
{forms.map(row => (
<TableRow key={row.id}>
//the TableCell below where I am trying to display childName
<TableCell component={"th"} scope={"row"}>
{row.children[0].childName}
</TableCell>
<TableCell>{row.timeIn}</TableCell>
<TableCell>{row.timeOut}</TableCell>
<TableCell>{row.parentName}</TableCell>
<TableCell>{row.shoeBoxNumber}</TableCell>
</TableRow>
))}
</TableBody>
Below is the full error screenshot:
Below is my state, I'm using React hooks:

Try to add validation: if array is not empty:
{row.children && row.children.length && row.children[0].childName}
<TableBody>
{forms.map(row => (
<TableRow key={row.id}>
//the TableCell below where I am trying to display childName
<TableCell component={"th"} scope={"row"}>
{row.children && row.children.length && row.children[0].childName}
</TableCell>
<TableCell>{row.timeIn}</TableCell>
<TableCell>{row.timeOut}</TableCell>
<TableCell>{row.parentName}</TableCell>
<TableCell>{row.shoeBoxNumber}</TableCell>
</TableRow>
))}
</TableBody>

you can add a validation to check if you array exist with data
<TableBody>
{forms.map((row)=> (
<TableRow key={row.id}>
//the TableCell below where I am trying to display childName
if(row.children[0]){
return (
<TableCell component={"th"} scope={"row"}>
{row.children[0].childName}
</TableCell>
)
}
<TableCell>{row.timeIn}</TableCell>
<TableCell>{row.timeOut}</TableCell>
<TableCell>{row.parentName}</TableCell>
<TableCell>{row.shoeBoxNumber}</TableCell>
</TableRow>
))}
</TableBody>

Related

i am trying to render Svg icons in a table , using material ui , in a react application. However, i see duplicate icons for different rows, any ideas?

I have an array of objects, where each object has a cryptocurrency-Id. i am using map to render a table and for rendering the token-image in the table i am calling a function: find_corresponding_icon(crypto-name), this function takes the crypto-name as a parameter and returns an image corresponding to it.I am seeing duplicate images rendering in my table.
import {ReactComponent as EthIcon} from '../../assets/eth.svg'
import {ReactComponent as DaiIcon} from '../../assets/dai.svg'
import {ReactComponent as UsdtIcon} from '../../assets/usdt.svg'
useEffect(()=>{
async function api_call(){
let res = await getTokenInfo()
setCurrecnyInfo(res.data.message) //setting state with an array of json objects
//currencyInfo=[{currencyId:1,tokenName:'Ethereum',Amount:312},
//{currencyId : 2, tokenName:'Dai',Amount:182},{currencyId : 3
, // tokenName:'USDT',Amount:882}]
}
api_call();
},[])
function find_corresponding_icon(CurrencyId){
if(CurrencyId === 1)
return <EthIcon />
else if(CurrencyId === 2)
return <DaiIcon />
else if(CurrencyId === 3)
return <UsdtIcon />
}
return (
<TableContainer component={Paper}>
<Table sx={{ minWidth: 650 }} aria-label="simple table">
<TableHead>
<TableRow>
<TableCell>TokenName</TableCell>
<TableCell>Name</TableCell>
<TableCell>Amount($)</TableCell>
</TableRow>
</TableHead>
<TableBody>
{rows.map((row,id) => (
<TableRow key={id}>
<TableCell component="th" scope="row">{find_corresponding_icon(row.currencyId)}</TableCell>
<TableCell align="right">{row.tokenName}</TableCell>
<TableCell align="right">{row.Amount}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
)
The result looks like so:
i am very sure all the icons look different, so there should not be a repetition

How to display all db items on a table

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} />

How to hide/show column based on if statement using Material-ui?

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>

Resetting state based upon choice

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>}

Table ordering with a map

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.

Categories

Resources