Toggle specific row with hooks - reactjs

Error in toggleHidden(key) [error: expecting 0 args but got 1] . kindly suggest corrections top toggle with key for particular row.
code
const [isOpen, setIsOpen] = React.useState(false);
const toggle = () => setIsOpen(!isOpen);
const[isHidden , setIsHidden] = React.useState(true)
const toggleHidden = () => setIsHidden(!isHidden)
const data = [
{
"name": "gvf",
"email": "abc",
"companyname": "xyz",
"address": "abcy"
},
{
"name": "abi",
"email": "dhf",
"companyname": "dhd",
"address": "fhfh"
}
]
return (
<div>
<Row>
<Col>
<table className="table table-hover table-striped table-sm">
<thead className="thead-dark">
<tr>
<th>Name</th>
<th>Email</th>
<th>CompanyName</th>
<th>Address</th>
</tr>
</thead>
<tbody>
{data.map((a , key) => (
<tr key={key}>
<td><Button onClick = {toggleHidden}>Click</Button>
{!isHidden && <p>Hello ABIII</p> }
</td>
<td>{a.name}</td>
<td>{a.email}</td>
<td>{a.address}</td>
<td>{a.companyname}</td>
</tr>
))}
</tbody>
</table>
</Col>
)
}

Just change the state to be an array and "pop"/"push" keys into it on toggle, then declare a curried handler that accepts a key, and performs proper toggle logic. I removed isOpen state since it was not used in the example, however you can change it the same way that isHidden state and toggler was changed:
const [ isHiddenList, setIsHiddenList ] = React.useState([])
const toggleHidden = key => () => {
setIsHiddenList(
isHiddenList.includes(key)
? isHiddenList.filter(existingKey => existingKey !== key)
: [ ...isHiddenList, key ]
);
};
const data = [
{
"key": "1"
"name": "gvf",
"email": "abc",
"companyname": "xyz",
"address": "abcy"
},
{
"key": "2"
"name": "abi",
"email": "dhf",
"companyname": "dhd",
"address": "fhfh"
}
]
return (
<div>
<Row>
<Col>
<table className="table table-hover table-striped table-sm">
<thead className="thead-dark">
<tr>
<th>Name</th>
<th>Email</th>
<th>CompanyName</th>
<th>Address</th>
</tr>
</thead>
<tbody>
{
data.map(({ key, name, email, companyname, address }) => {
const isHidden = isHiddenList.includes(key);
return (
<tr key={key}>
<td><Button onClick={toggleHidden(key)}>Click</Button>
{!isHidden && <p>Hello ABIII</p> }
</td>
<td>{a.name}</td>
<td>{a.email}</td>
<td>{a.address}</td>
<td>{a.companyname}</td>
</tr>
);
})
}
</tbody>
</table>
</Col>
</Row>
</div>
)
disclaimer - key should be part of data items for consistency, dynamically generated iteration index does not guarantee that keys will be assigned properly.

Related

React: Uncaught TypeError: Cannot read properties of undefined (reading '0') error

It is my first time js and react.js project. and I have a problem with printing out json array data.
Here's my code
const [appData, setAppData] = useState({});
const [appdevData, setAppdevData] = useState('');
axios
.all([
.get(url1)
.get(url2)
])
.then(
axios.spread((res1, res2) => {
const data1 = res1.data;
const data2 = res2.data;
setAppData(data1);
setAppdevData(data2().results[0].developer.name);
})
}, []);
return (
<section className={styles.itemDisplaySection}>
<div className={styles.itemDisplayFlex}>
<table className={styles.itemDisplayTable}>
<tr>
<td>APP ID</td>
<td>{appData.app_id}</td>
</tr>
<tr>
<td>APP Type</td>
<td>{appData.type}</td>
</tr>
<tr>
<td>Developer</td>
<td>{appdevData.results[0].developer.name}</td>
</tr>
<tr>
<td>Release Date</td>
<td>{appData.release_date}</td>
</tr>
</table>
</div>
</section>
);
and here is my appData.json, and appdevData.json data.
appdata.json
{
"app_id": 1089090,
"name": "testdata",
"header_url": "https://cdn.akamai.steamstatic.com/steam/apps/1089090/header_koreana.jpg?t=1658473684",
"release_date": "2020-03-26",
"type": "game",
"basegame_id": null
}
appdevData.json
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"app_dev_id": 76,
"app": "Django-server-url",
"developer": {
"developer_id": 65,
"name": "SMILE"
}
}
]
}
but still there is print issue with results[] array.
here is my error code.
// with appdevData.results[0].developer.name
Cannot read properties of undefined (reading '0')
I've been trying to fix with map func, and props components and still have problem with it.
I know it's a simple array print out issue, but I can't find a way to fix this error.
plz help me.
When setting your appdevData change the code to (data2 is not a function):
axios.spread((res1, res2) => {
const data1 = res1.data;
const data2 = res2.data;
setAppData(data1);
if (!data2.results || data2.results.length == 0) return;
setAppdevData(data2.results[0].developer.name);
})
Also, you could set your default appData state to null and add conditional rendering to prevent errors due to accessing properties during load.
Finally, you should display the appdevData state instead of appdevData.results[0].developer.name:
const [appData, setAppData] = useState(null);
const [appdevData, setAppdevData] = useState('');
...
if (!appData) return <>Loading data...</>
return (
<section className={styles.itemDisplaySection}>
<div className={styles.itemDisplayFlex}>
<table className={styles.itemDisplayTable}>
<tr>
<td>APP ID</td>
<td>{appData.app_id}</td>
</tr>
<tr>
<td>APP Type</td>
<td>{appData.type}</td>
</tr>
<tr>
<td>Developer</td>
<td>{appdevData}</td>
</tr>
<tr>
<td>Release Date</td>
<td>{appData.release_date}</td>
</tr>
</table>
</div>
</section>
);

Why isn't jsonData reading the file?

i have a json file:
[ {
"symbol" : "SPY",
"type" : "etf"
}, {
"symbol" : "CMCSA",
"type" : "stock"
}, {
"symbol" : "KMI",
"type" : "stock"
}, {
"symbol" : "INTC",
"type" : "stock"
}, {
"symbol" : "MU",
"type" : "stock"
},
...
And I'm trying to read it into the table:
const Home = () =>{
const displayStockCodes = (info) =>{
JsonData.map(
(info)=>{
return(
<tr>
<td>{info.symbol}</td>
<td>{info.type}</td>
</tr>
)
}
);
};
return (
<div>
<table class="table table-striped">
<thead>
<tr>
<th>Symbol</th>
<th>Type</th>
</tr>
</thead>
<tbody>
{displayStockCodes}
</tbody>
</table>
</div>
);
};
export default Home;
I tried to do it according to the guide, but in the end only Symbol and Type are displayed on the page, and the data itself is not output. Maybe I need to add something else?
displayStockCodes is a function but you are not calling it in the tbody you need to call that function.
displayStockCodes also doesn't return anything you need to ensure it returns some JSX code.
const Home = () =>{
const displayStockCodes = (info) =>{
// 2. you need to return
return JsonData.map(
(info)=>{
return(
<tr>
<td>{info.symbol}</td>
<td>{info.type}</td>
</tr>
)
}
);
};
return (
<div>
<table className="table table-striped"> <!-- use className here instead of class -->
<thead>
<tr>
<th>Symbol</th>
<th>Type</th>
</tr>
</thead>
<tbody>
<!-- you need to call this -->
{displayStockCodes()}
</tbody>
</table>
</div>
);
};
export default Home;
const Home = () => {
const JsonData = [
{
symbol: 'SPY',
type: 'etf',
},
{
symbol: 'CMCSA',
type: 'stock',
},
{
symbol: 'KMI',
type: 'stock',
},
{
symbol: 'INTC',
type: 'stock',
},
{
symbol: 'MU',
type: 'stock',
},
];
const displayStockCodes = () => {
return JsonData.map((info) => (
<tr>
<td>{info.symbol}</td>
<td>{info.type}</td>
</tr>
));
};
return (
<div>
<table class="table table-striped">
<thead>
<tr>
<th>Symbol</th>
<th>Type</th>
</tr>
</thead>
<tbody>{displayStockCodes()}</tbody>
</table>
</div>
);
};
export default Home;
The output:

react hooks toggle for specific row

Please clarify my problem of toggle for specific row of the table with react hooks. whenever I press click.. it opens for every row and by default the table head is moving right it is not constant.
Error in toggleHidden(key). How to correct my toggleHidden function?
const[isHidden , setIsHidden] = React.useState(true)
const toggleHidden = () => setIsHidden(!isHidden)
const data = [
{
"name": "gvf",
"email": "abc",
"companyname": "xyz",
"address": "abcy"
},
{
"name": "abi",
"email": "dhf",
"companyname": "dhd",
"address": "fhfh"
}
]
return (
<div>
<Row>
<Col>
<table className="table table-hover table-striped table-sm">
<thead className="thead-dark">
<tr>
<th>Name</th>
<th>Email</th>
<th>CompanyName</th>
<th>Address</th>
</tr>
</thead>
<tbody>
{data.map((a , key) => (
<tr key={a.name}>
<td><Button onClick = {toggleHidden(key)}>Click</Button>
{!isHidden && <p>Hello ABIII</p> }
</td>
<td>{a.name}</td>
<td>{a.email}</td>
<td>{a.address}</td>
<td>{a.companyname}</td>
</tr>
))}
</tbody>
</table>
</Col>
</Row> </div>
you need define the specific row - when You mapping:
{data.map(a => (
)}
try add key attribute to every item in collection like this:
{data.map((a, key) => (
))}
then pass to Your item:
<tr key={key}>
So now every is unique - so if You pass that key to your function:
<Button onClick = {toggleHidden(key)}>
the program should know which specific item execute toggleHidden function

How can I render data within nested objects in react?

I am working with an API that contains nested objects and I am not sure how to display it. I am reading about using Object.keys but not sure how to do it... help please...
Here is the react code. I need to render prices dynamically.
<div>
<Table responsive striped bordered hover variant="dark">
<thead>
<tr>
<th>Rank</th>
<th>Name</th>
<th>Symbol</th>
<th>Price</th>
<th>% Change</th>
<th>Market Cap</th>
</tr>
</thead>
<tbody>
{Object.keys(
cryptos.map(crypto => (
<tr key={crypto.id}>
<td>{crypto.cmc_rank}</td>
<td>
<Link to={`/crypto/${crypto.id}`}>{crypto.name}</Link>
</td>
<td>{crypto.symbol}</td>
<td>{`price should be displayed here `}</td>
<td>{`price change should be displayed here `}</td>
<td>{`market cap should be displayed here `}</td>
</tr>
))
)}
</tbody>
</Table>
</div>
Here is the data source
"data": [
{
"id": 1,
"name": "Bitcoin",
"symbol": "BTC",
"slug": "bitcoin",
"num_market_pairs": 8203,
"date_added": "2013-04-28T00:00:00.000Z",
"tags": [
"mineable"
],
"max_supply": 21000000,
"circulating_supply": 18376356,
"total_supply": 18376356,
"platform": null,
"cmc_rank": 1,
"last_updated": "2020-05-13T10:30:30.000Z",
"quote": {
"USD": {
"price": 8920.68810523,
"volume_24h": 40828691066.513,
"percent_change_1h": 0.107841,
"percent_change_24h": 1.62343,
"percent_change_7d": -2.5838,
"market_cap": 163929740386.67194,
"last_updated": "2020-05-13T10:30:30.000Z"
}
}
},
Here you go with a solution
<div>
<Table responsive striped bordered hover variant="dark">
<thead>
<tr>
<th>Rank</th>
<th>Name</th>
<th>Symbol</th>
<th>Price</th>
<th>% Change</th>
<th>Market Cap</th>
</tr>
</thead>
<tbody>
{
cryptos.length &&
cryptos.map(crypto => (
<tr key={crypto.id}>
<td>{crypto.cmc_rank}</td>
<td>
<Link to={`/crypto/${crypto.id}`}>{crypto.name}</Link>
</td>
<td>{crypto.symbol}</td>
<td>{crypto.quote.USD.price}</td>
<td>{crypto.quote.USD.price * crypto.quote.USD.percent_change_1h}</td>
<td>{crypto.quote.USD.market_cap}</td>
</tr>
)
)}
</tbody>
</Table>
</div>
Here is the data source
"data": [
{
"id": 1,
"name": "Bitcoin",
"symbol": "BTC",
"slug": "bitcoin",
"num_market_pairs": 8203,
"date_added": "2013-04-28T00:00:00.000Z",
"tags": [
"mineable"
],
"max_supply": 21000000,
"circulating_supply": 18376356,
"total_supply": 18376356,
"platform": null,
"cmc_rank": 1,
"last_updated": "2020-05-13T10:30:30.000Z",
"quote": {
"USD": {
"price": 8920.68810523,
"volume_24h": 40828691066.513,
"percent_change_1h": 0.107841,
"percent_change_24h": 1.62343,
"percent_change_7d": -2.5838,
"market_cap": 163929740386.67194,
"last_updated": "2020-05-13T10:30:30.000Z"
}
}
},
Price changed I have considered percent_change_1h * price. Check for cryptos.length before doing map operation.
I have no idea why you have {Object.keys( in there... remove it.
<div>
<Table responsive striped bordered hover variant="dark">
<thead>
<tr>
<th>Rank</th>
<th>Name</th>
<th>Symbol</th>
<th>Price</th>
<th>% Change</th>
<th>Market Cap</th>
</tr>
</thead>
<tbody>
{ cryptos.map(crypto => (
<tr key={crypto.id}>
<td>{crypto.cmc_rank}</td>
<td>
<Link to={`/crypto/${crypto.id}`}>{crypto.name}</Link>
</td>
<td>{crypto.symbol}</td>
<td>{`price should be displayed here `}</td>
<td>{`price change should be displayed here `}</td>
<td>{`market cap should be displayed here `}</td>
</tr>
)) }
</tbody>
</Table>
</div>
Having Object.keys() essentially returns an array containing the indexes of the array you map from cryptos. React needs an array of elements, so you just need iterate through the elements of cryptos, and map each item to something React can render.
For example:
const dataList = [{ key:'a', value:'Hello' }, { key:'b', value:'World' }];
<div>
{ dataList.map(data => <div key={ data.key }>{ data.value }</div>) }
</div>
Will render
<div>
<div>Hello</div>
<div>World</div>
</div>

react mapping function not working

hey all i have this array of objects
this.state = {
users :[{
userid:'1',
fullName :'eddyabikhalil',
dob:'10/03/1994',
gender:'M',
loan:[{
loanid:'1',
date:'20/7/2012',
loanValue:'100$',
},
{
loanid:'2',
date:'21/4/2014',
loanValue:'200$',
},
{
loanid:'3',
date:'20/12/2015',
loanValue:'300$',
}]
},
userid:'2',
fullName :'joe salloum',
dob:'11/04/1993',
gender:'M',
loan:[{
loanid:'4',
date:'20/7/2012',
loanValue:'500$',
},
{
loanid:'5',
date:'21/4/2017',
loanValue:'600$',
},
{
loanid:'6',
date:'20/12/2012',
loanValue:'700$',
}
],
}]
}
}
so i wrote this function to map inside of this array of object:
renderTable(userValue) {
let HTML = [];
let groupedVals = groupBy(userValue, 'userid');
let usersObj = [];
map(groupedVals, (value, key) => {
let userss = {
FullName: value.fullName,
dob: value.dob,
gender: value.gender,
loans: []
}
map(value, (subValue) => {
userss.loans.push(subValue.loanValue)
})
usersObj.push(userss);
})
map(usersObj, (val) => {
HTML.push(<tr>
<td>
{val.FullName}
</td>
<td>
{val.dob}
</td>
<td>
{val.gender}
</td>
<td>
{val.loans.join(',')}
</td>
</tr>
)
})
return HTML;
}
i want to make a table with the following fields: fullName, dob, gender and loan
i want to show that userid = 1 have multiple loan value in one td
so i created this table:
render() {
return (
<div className="container">
<table className="table table-striped">
<thead>
<tr>
<td>FullName</td>
<td>dob</td>
<td>gender</td>
<td>loans</td>
</tr>
</thead>
<tbody>
{
this.state.users &&
this.renderTable(this.state.users)
}
</tbody>
</table>
</div>
);
}
any help guys? thanks in advance
render() {
return (
<div className="container">
<table className="table table-striped">
<thead>
<tr>
<td>FullName</td>
<td>dob</td>
<td>gender</td>
<td>loans</td>
</tr>
</thead>
<tbody>
{
this.state.users.map((user) => (
<tr>
<td>{user.fullName}</td>
<td>{user.dob}</td>
<td>{user.gender}</td>
<td>{user.loan.map((loan) => { return (loan.id + ",") })}</td>
</tr>
))
}
</tbody>
</table>
</div>
);
}

Resources