when i create table with data from api the rows are duplicated? - javascript

import React from 'react'
import './user.css'
const User = ({ id, email, name, onDelete }) => {
const handleDelete = () => {
onDelete(id);
}
return (
<table className='table'>
<thead>
<tr>
<th>Name</th>
<th>Email</th>
<th>edit</th>
<th>delete</th>
</tr>
</thead>
<tbody>
<tr>
<td>{name}</td>
<td>{email}</td>
<td>
<button>edit</button>
<button onClick={handleDelete}>delete</button>
</td>
</tr>
</tbody>
</table>
)
}
export default User

You're creating a new table for every user. That's why your headers are duplicated. You only need a new row for every user instead of an entire table for each user.
I'd separate the UserTable and the UserRow.
// UserTable.jsx
import React from 'react'
import './user.css'
import './UserRow'
const UserTable = ({ users, onDelete }) => {
return (
<table className='table'>
<thead>
<tr>
<th>Name</th>
<th>Email</th>
<th>edit</th>
<th>delete</th>
</tr>
</thead>
<tbody>
{users.map(user => {
<UserRow key={user.id} userId={user.id} userName={user.name} email {user.email} onDelete={onDelete} />onDelete={onDelete} />
})
}
</tbody>
</table>
)
}
export default UserTable
// UserRow.jsx
import React from 'react'
import './user.css'
const UserRow = ({ userId, email, userName, onDelete }) => {
const handleDelete = () => {
onDelete(userId);
}
return (
<tr>
<td>{userName}</td>
<td>{email}</td>
<td>
<button>edit</button>
<button onClick={handleDelete}>delete</button>
</td>
</tr>
)
}
export default UserRow

Related

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

if ternario does not work, function has value but never used says

I am new with programing and I want to use if ternario, but it doesn't work. I have two functions and I create a third function to show one of them or the other. It is an application in ReactJS. Below is the code:
import { Table } from "react-bootstrap";
import { Link } from "react-router-dom";
import { useCartContext } from "../../Context/CartContext";
const emptyCart = () => {
return(
<>
<div>
<h3>The Cart is empty</h3>
<p>
Return to home to see our products
</p>
<Link to='/' ><button className="btn btn-info"> Home </button></Link>
</div>
</>
);
};
const CartFunction = () => {
const { list, totalPrice } = useCartContext();
return (
<Table striped hover>
<thead>
<tr>
<th>Product</th>
<th>Title</th>
<th>Quantity</th>
<th>Price</th>
</tr>
</thead>
<tbody>
{list.map((varietal) => (
<tr key={varietal.id}>
<td>
<img
src={varietal.pictureUrl}
alt='img'
style={{ width: "82px" }}
/>
</td>
<td>{varietal.title}</td>
<td>{varietal.count}</td>
<td>${varietal.price}</td>
</tr>
))}
</tbody>
<thead>
<tr>
<td colSpan="3">Total</td>
<td>${totalPrice()}</td>
</tr>
</thead>
</Table>
);
};
const CartComponent = () => {
const { list } = useCartContext();
return (
<>
{list.length !== 0 ? <CartFunction /> : <emptyCart />}
</>
);
};
export default CartComponent;
Visual Code it says that emptyCard has a value but it is never used. If there is someone that could help me I would appreciate it. Cheers

React don't render a map function of an Axios call

I'm trying to make a shopping cart table in which it shows an image, name of the product and a remove button. I've the id of each product from the localStorage and call all the data of that id with Axios.get(by id).
I'd created a table to show the price, image and name of the product, but my .map function don't show the info in the website (even though I can see it with a console.log). Here is the code:
import Axios from "axios";
import React from "react";
function ClientCardBlock() {
let memory = window.JSON.parse(localStorage.getItem("toy"));
console.log(memory); **this log shows me that all the IDs are now in an array**
const renderItems = () => {
memory.map(
async (toy_id) =>
await Axios.get(`http://************/${toy_id}`).then(
(response) => {
const toy = response.data;
console.log(toy.price); **this log show me the price of each toy, so it's working**
return (
<tr key={toy._id}>
<th>
<img
alt=""
className="card-img-top embed-responsive-item"
src={`http://*********/${toy.images}`}
/>
</th>
<th>$ {toy.price}</th>
<th>
<button>Remove</button>
</th>
</tr>
);
}
)
);
};
return (
<div>
<table className="table table-bordered">
<thead>
<tr>
<th scope="col">Image product</th>
<th scope="col">Product</th>
<th scope="col">Remove</th>
</tr>
</thead>
<thead>{renderItems()}</thead>
</table>
</div>
);
}
export default ClientCardBlock;
Normally you'd be able to just change it so that renderItems is a functional component.
function RenderItems() {
return memory.map...(etc)
}
...
<thead><RenderItems /></thead>
but since this is an async function, you need to use a useEffect. This useEffect gets the data and saves it into your component state. Then once it exists, it will render later. The key point is to seperate the fetching from the rendering.
function ClientCardBlock() {
const [data, setData] = useState([]);
useEffect(() => {
/* this runs on component mount */
const memory = window.JSON.parse(localStorage.getItem("toy"));
Promise.all(memory.map((toy_id) => Axios
.get(`http://************/${toy_id}`)
.then((response) => response.data)))
/* Wait on the Promise.All */
.then(newData => {
/* Set the data locally */
setData(newData);
});
}, []);
return (
<div>
<table className="table table-bordered">
<thead>
<tr>
<th scope="col">Image product</th>
<th scope="col">Product</th>
<th scope="col">Remove</th>
</tr>
</thead>
<thead>
{data.map(toy => (
<tr key={toy._id}>
<th>
<img
alt=""
className="card-img-top embed-responsive-item"
src={`http://*********/${toy.images}`}
/>
</th>
<th>$ {toy.price}</th>
<th>
<button>Remove</button>
</th>
</tr>
)}
</thead>
</table>
</div>
);
}
export default ClientCardBlock;

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