Acessing specific table data from table row in React - reactjs

It is my first time fetching data from an API and I'm quite new to React. Would be greatly appreciated if someone could help!
I am having trouble accessing some data inside a table row. I am trying to access the name property by clicking the row. What I want is to copy the name property from clicking the specific row.
Also, my useEffect keeps fetching data non-stop. I've tried to change the dependencies but it keeps doing it no matter what I do. I am passing the endpoint to the API from the button click.
Another thing is that when I am getting the data I would like to access every index of the array members but I tried and couldn't figure it out. So I am only accessing the index[1] (resp.guild.members[1].characters).
My Code:
import React, { useState, useEffect } from "react";
const Tabledata = ({ guildName }) => {
const [members, setMembers] = useState([]);
const [membersOnline, setMembersOnline] = useState([]);
useEffect(() => {
fetch(`https://api.tibiadata.com/v2/guild/${guildName}.json`)
.then((res) => res.json())
.then((resp) => {
console.log(resp);
setMembers(resp.guild.members[1].characters);
setMembersOnline(() =>
members.filter((player) => player.status !== "offline")
);
})
.catch((err) => console.log(err));
}, [members, guildName]);
return (
<div className="container">
<h1>Enemies Online</h1>
<table className="table table-bordered">
<thead>
<tr>
<th>Name</th>
<th>Level</th>
<th>Vocation</th>
<th>Status</th>
</tr>
</thead>
<tbody>
{membersOnline.map((d, id) => (
<tr
key={d.id}
onClick={(e) => {
console.log(this.d.name);
navigator.clipboard.writeText(`exiva "${e.target.value}`);
}}
>
<td>{d.name}</td>
<td>{d.level}</td>
<td>{d.vocation}</td>
<td>{d.status}</td>
</tr>
))}
</tbody>
</table>
</div>
);
};
export default Tabledata;
Code working:
import React, { useState, useEffect } from "react";
const Tabledata = ({ guildName }) => {
// const [members, setMembers] = useState([]);
const [membersOnline, setMembersOnline] = useState([]);
const [header, setHeader] = useState("");
useEffect(() => {
fetch(`https://api.tibiadata.com/v2/guild/${guildName}.json`)
.then((res) => res.json())
.then((resp) => {
const members = resp.guild;
setHeader(resp.guild.data.name);
const allCharacters = members.reduce((accum, iter) => {
accum.push(...iter.characters);
return accum;
}, []);
console.log(members);
console.log(allCharacters);
setMembersOnline(() =>
allCharacters.filter((player) => player.status !== "offline")
);
})
.catch((err) => console.log(err));
}, [guildName]);
return (
<div className="container">
<h1>{header}</h1>
<table className="table table-bordered">
<thead>
<tr>
<th>Name</th>
<th>Level</th>
<th>Vocation</th>
<th>Status</th>
</tr>
</thead>
<tbody>
{membersOnline.map((d) => (
<tr
key={d.id}
onClick={(e) => {
navigator.clipboard.writeText(
`exiva "${e.currentTarget.children[0].innerText}`
);
}}
>
<td>{d.name}</td>
<td>{d.level}</td>
<td>{d.vocation}</td>
<td>{d.status}</td>
</tr>
))}
</tbody>
</table>
</div>
);
};
export default Tabledata;
However, if I try to assign resp.guild to members somehow reduce won't work..something like this:
import React, { useState, useEffect } from "react";
const Tabledata = ({ guildName }) => {
const [members, setMembers] = useState([]);
const [membersOnline, setMembersOnline] = useState([]);
useEffect(() => {
fetch(`https://api.tibiadata.com/v2/guild/${guildName}.json`)
.then((res) => res.json())
.then((resp) => {
setMembers(resp.guild);
setHeader(resp.guild.data.name);
const allCharacters = members.reduce((accum, iter) => {
accum.push(...iter.characters);
return accum;
}, []);
setMembersOnline(() =>
allCharacters.filter((player) => player.status !== "offline")
);
})
.catch((err) => console.log(err));
}, [members, guildName]);
return (
<div className="container">
<h1>Enemies Online</h1>
<table className="table table-bordered">
<thead>
<tr>
<th>Name</th>
<th>Level</th>
<th>Vocation</th>
<th>Status</th>
</tr>
</thead>
<tbody>
{membersOnline.map((d, id) => (
<tr
key={d.id}
onClick={(e) => {
console.log(this.d.name);
navigator.clipboard.writeText(
`exiva "${e.target.value.innerText}`
);
}}
>
<td>{d.name}</td>
<td>{d.level}</td>
<td>{d.vocation}</td>
<td>{d.status}</td>
</tr>
))}
</tbody>
</table>
</div>
);
};
export default Tabledata;
It will throw an exception at reduce saying it is not a function

I have refactored your code, and it is working in a code sandbox here with no errors in rendering.
I made a few changes after looking at your updated question and looking at the API that you are using.
I removed members as a state object
I am setting the key value of the map function to the index of the array, because id is not a property of the members in the JSON response body.
I removed members from the dependency array as it no longer a managed state
I removed setHeader because it is not defined anywhere in your code example
I changed the filter to return offline members because there were literally no members online at the time of writing this.
Please reference the code sandbox I linked in order to fully understand any issues you come across implementing my code.
As a note: navigator.clipboard.writeText() as you have written it does not work in the code sandbox, but a console.log will show the value that is being written to the clipboard is correct. Questions about clipboard should be asked in their own stack overflow post.
const Tabledata = ({ guildName }) => {
const [membersOnline, setMembersOnline] = useState([]);
useEffect(() => {
fetch(`https://api.tibiadata.com/v2/guild/${guildName}.json`)
.then((res) => res.json())
.then((resp) => {
const { members } = resp.guild;
const allCharacters = members.reduce((accum, iter) => {
accum.push(...iter.characters);
return accum;
}, []);
setMembersOnline(
allCharacters.filter(({ status }) => status === "offline")
);
})
.catch((err) => console.log(err));
}, [guildName]);
return (
<div className="container">
<h1>Enemies Online</h1>
<table className="table table-bordered">
<thead>
<tr>
<th>Name</th>
<th>Level</th>
<th>Vocation</th>
<th>Status</th>
</tr>
</thead>
<tbody>
{membersOnline.map((d, i) => (
<tr
key={i}
onClick={(e) => {
navigator.clipboard.writeText(
`exiva ${e.currentTarget.children[0].innerText}`
);
}}
>
<td>{d.name}</td>
<td>{d.level}</td>
<td>{d.vocation}</td>
<td>{d.status}</td>
</tr>
))}
</tbody>
</table>
</div>
);
};
export default Tabledata

Related

Rendering a Table Axios ReactJS

i'm trying to render all booked slots using a table, i suspect the problem is with the Axios call since i get "Cannot GET /api/get/week1" but i'm not sure how to test this theory or how check if the array actually contains any values, any help would be greatly appreciated!
function BookingTable() {
useEffect(() => {
Axios.get('http://localhost:3001/api/get/week1').then((response) => {
setIsBooked(response.data)
console.log(response.data);
})
}, []);
const [isBooked, setIsBooked] = useState([])
const renderTableData = () => {
return isBooked.map((val) => (
<tr class>
<td>{val.booked}</td>
</tr>))
}
return (
<table id="table">
<thead>
<tr>
<th>Booked</th>
</tr>
</thead>
<tbody>
{renderTableData}
</tbody>
</table>
)
}
export default BookingTable
you call function incorrectly call it like renderTableData() working demo link
import axios from "axios";
import { useEffect, useState } from "react";
import "./styles.css";
function BookingTable() {
const [isBooked, setIsBooked] = useState([]);
useEffect(() => {
axios.get("https://jsonplaceholder.typicode.com/posts").then((response) => {
setIsBooked(response.data);
});
}, []);
const renderTableData = () => {
return isBooked?.map((val) => (
<tr class>
<td>{val.id}</td>
</tr>
));
};
return (
<table id="table">
<thead>
<tr>
<th>Booked</th>
</tr>
</thead>
<tbody>{renderTableData()}</tbody>
</table>
);
}
export default BookingTable;

want to pass id from mongodb database collection in react table and react form using button

I am doing a project in which I need to show all the product information from the MongoDB database in UI. This data will be shown in UI in tabular form. So I want to use react table. In each row, there will be a button to delete that product information from the UI and also from MongoDB. I am trying to pass the id to button but every time I am getting undefined. value. How can I pass MongoDB product id correctly to react table?
though I am doing it in the following way. But I really want to do it in react table.
import axios from 'axios';
import React, { useEffect, useState } from 'react';
import { useAuthState } from 'react-firebase-hooks/auth';
import auth from '../../firebase.init';
import './Table.css'
const Table = () => {
const [data, setData] = useState([])
const [user] = useAuthState(auth)
const email = user.email
useEffect(() => {
fetch(`https://polar-castle-01342.herokuapp.com/inventory`)
.then((response) => response.json())
.then((data) => setData(data))
}, [])
const handleDeleteButton = async id => {
const proceed = window.confirm('Are you sure you want to delete this product?')
if (proceed) {
const url = `https://polar-castle-01342.herokuapp.com/inventory/${id}`
const response = await axios.delete(url)
const remaining = data.filter(item => item._id !== id)
setData(remaining)
}
}
return (
<div className='mt-5 table-responsive'>
<h1 className='text-center mb-3'>Inventory Products</h1>
<table border={1} cellPadding={5} className='w-100'>
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Price</th>
<th>Quantity</th>
<th>Supplier Name</th>
<th>Options</th>
</tr>
</thead>
<tbody>
{data.map(product => (
<tr key={product._id}>
<td>{product._id}</td>
<td>{product.name}</td>
<td>{product.price}</td>
<td>{product.quantity}</td>
<td>{product.supplierName}</td>
<td><button onClick={() => handleDeleteButton(product._id)} className='delete-button'>Delete</button></td>
</tr>
))}
</tbody>
</table>
</div>
);
};
export default Table;
You should write like this
`const handleDeleteButton = async id => {
const proceed = window.confirm('Are you sure you want to delete this product?')
if (proceed) {
const url = `https://polar-castle-01342.herokuapp.com/inventory/${id}`
const response = await axios.delete(url)
const remaining = data.filter(item => item._id !== id)
setData(remaining)
}
}and useEffect(() => {
fetch(https://polar-castle-01342.herokuapp.com/inventory)
.then((response) => response.json())
.then((data) => setData(data))
}, [handleDeleteButton])`
I hope it'll useful

how to fix problem on No data available in table in data table react js

I'm new in react js and I want to display all data from database into data table but I'm getting an error of No data available in table. I also added the getStudent to the useEffect so that it would run continuously
this is my useState and useEffect snippet code:
const [student, setStudent] = useState([]);
const getStudent = async () => {
try {
const response = await fetch("http://localhost:5000/admin/get_allstudent");
const data = await response.json();
setStudent(data);
} catch (err) {
console.error(err.message);
}
};
const dataTable = () => {
$(document).ready(function () {
$("#example").DataTable();
});
};
useEffect(() => {
setInterval(dataTable, 1000);
getStudent();
}, []);
and this is my render:
<table id="example" className="display ">
<thead>
<tr>
<th>Name</th>
<th>Username</th>
<th>Action</th>
</tr>
</thead>
<tbody>
{student.map((item, index) => {
return (
<tr key={item.stu_id}>
<td>{item.stu_name}</td>
<td>{item.stu_username}</td>
<td>
<Edit item={item} />
<button className="btn btn-danger" onClick={()=> deleteStudent(item.stu_id)}
>
Delete
</button>
</td>
</tr>
);
})}
</tbody>
</table>;
And this is the output
i don't know about jQuery part of your code and i don't think that is necessary
first try to remove that part and then check if student has value or not
you can check the student value by using useEffect
useEffect(() => {
if (student) console.log('data is ok ' , student)
}, [student]);
if the message showed up in console and it was not empty
then there should be no problem

Table is not showing in reactjs useTable hook when data is being accessed from backend in Spring boot via axios

Sometimes when I save table which has two products in backend (it's a product table display on frontend) shows but not everytime when I call the component as expected.
The component is called through routing in App.js and through /productshow url. In console though fetched data.
I have tried simple h1 tag in place of table and it works fine. Some error is definitely occuring in rendering the table
const DisplayProduct = () => {
toast.success("in Display");
const [product, setProduct] = useState([]);
const getAllProductsFromServer = () => {
axios.get(`${base_url}/productshow`).then(
(response) => {
console.log(response);
setProduct(response.data);
console.log("Done");
},
(error) => {
console.log(error);
}
);
};
useEffect(() => {
getAllProductsFromServer();
}, []);
const columns = useMemo(() => COLUMNS, [])
const data = useMemo(() => product, [])
const TableInstance = useTable(
{
columns,
data,
}
)
const {
getTableProps,
getTableBodyProps,
headerGroups,
rows,
prepareRow,
} = TableInstance
return (
<table {...getTableProps()}>
<thead>
{headerGroups.map((headerGroup) => {
<tr {...headerGroup.getHeaderGroupProps()}>
{headerGroup.headers.map((column) => (
<th {...column.getHeaderProps()}>
{column.render('Header')}
</th>
))}
</tr>
})}
</thead>
<tbody {...getTableBodyProps()}>
{rows.map((row) => {
prepareRow(row)
return (
<tr {...row.getRowProps()}>
{row.cells.map((cell) => {
return <td {...cell.getCellProps()}>{cell.render('Cell')}</td>
})}
</tr>
)
})}
</tbody>
</table>
)
};
export default DisplayProduct;

searchfilter with using react hook(useEffect / useState)

I am trying to create a searchBar.
When I type some value on input, I would like my listitems from github api to be re-listed with the value on searchBar.
import './App.css';
function App() {
const [datas, setDatas] = useState([]);
const [userid, setUserid] = useState('');
const inputChanged = (event) => {
setUserid(event.target.value)
}
const searchBar = () => {
}
useEffect(() => {
fetch('https://api.github.com/search/repositories?q=react')
.then(response => response.json())
.then(data => {
setDatas(data.items)
})
},[])
return (
<div className="App">
<h1>Repositories</h1>
<input id="searchInput"type="text" placeholder="search" name="search" value={userid} onChange={inputChanged}/>
<button onClick={searchBar}>Search</button>
<table>
<tbody>
<tr>
<th>Name</th>
<th>URL</th>
</tr>
{
datas.map((data, index) =>
<tr key={index}>
<td>{data.full_name}</td>
<td><a href={data.html_url}>{data.html_url}</a></td>
</tr>
)
}
</tbody>
</table>
</div>
);
}
export default App;
Here is my code and the image of the localhost
useEffect has an array at the end, when left empty what's in useEffect only update once. You can add variables to that array, to update when that variable changes.
Here you need to write: useEffect(your function,[userid]);

Resources