Hi there I'm fairly new to react and I'm trying to create a student management app with React as a frontend and i can't seem to get the page to return a list of students since I tried working with the functions useHistory and useNavigate from react-router-dom to try redirect to an individual student component but I was unable to get them working on my project so I removed them.
The page was rendering the student objects from the backend API i created just fine before I tried implementing the two functions but now won't render any student object, all that is displayed are the table heads but not the table rows any help on what the problem would be appreciated
here is my hook component to fetch data before using useHistory & useNavigate
function GetAllStudents() {
const [students, setStudents] = useState([]);
const fetchData = async () => {
StudentService.getStudents() //axios service function used to fetch data
.then((res) => res.json())
.then((res) => {
const currentStudent = res.data;
setStudents(currentStudent); // try setStudents(res.data) if fails
})
.catch((err) => {
console.log(err);
});
// fetchData();
};
useEffect(() => fetchData(), []);
return (
<div class="container">
<div class="form container p-4">
<h1>Week 10 - React Frontend </h1>
<a href="/add" class="btn btn-success">
Add Student
</a>
</div>
<table class="table table-bordered">
<thead>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Email</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{students.map((student) => (
<tr key={student.id}>
<td> {student.firstname} </td>
<td> {student.lastname}</td>
<td> {student.email}</td>
<td>
<button className="btn btn-info">Edit</button>
<button
style={{ marginLeft: '10px' }}
className="btn btn-danger"
onclick="return confirm('Do you Really want to delete')">
Delete{' '}
</button>
</td>
</tr>
))}
</tbody>
</table>
</div>
);
}
export default GetAllStudents;
When I inspect elements on my browser it shows the state is not saving the objects to the array
I don't know what I misconfigured because even when I change the function to a class component that also previously worked properly doesn't display the objects anymore
import React, { Component } from 'react';
import StudentService from '../services/StudentService';
class GetAllStudents extends Component {
constructor(props) {
super(props);
this.state = {
students: [],
};
this.addStudent = this.addStudent.bind(this);
this.editStudent = this.editStudent.bind(this);
this.deleteStudent = this.deleteStudent.bind(this);
}
deleteStudent(id) {
StudentService.deleteStudent(id).then((res) => {
this.setState({
students: this.state.students.filter((student) => student.id !== id),
});
});
}
updateStudent(id) {
this.props.history.push(`/students/${id}`); // props(parameter) to navigate to edit student component
}
editStudent(id) {
this.props.history.push(`/edit/${id}`); // props(parameter) to navigate to edit student component
}
componentDidMount() {
StudentService.getStudents().then((res) => {
this.setState({ students: res.data }); //loads all students in database
});
}
addStudent() {
this.props.history.push('/add'); //function to navigate to edit student component with form to add student
}
render() {
return (
<div class="container">
<div class="form container p-4">
<h1>Week 10 - React Frontend </h1>
<a href="/add" class="btn btn-success">
Add Student
</a>
</div>
<table class="table table-bordered">
<thead>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Email</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{this.state.students.map((student) => (
<tr key={student.id}>
<td> {student.firstname} </td>
<td> {student.lastname}</td>
<td> {student.email}</td>
<td>
<button
onClick={() => this.updateStudent(student.id)}
className="btn btn-info">
Edit
</button>
<button
style={{ marginLeft: '10px' }}
onClick={() => this.deleteStudent(student.id)}
className="btn btn-danger"
onclick="return confirm('Do you Really want to delete')">
Delete{' '}
</button>
</td>
</tr>
))}
</tbody>
</table>
</div>
);
}
}
export default GetAllStudents;
when I check my backend it shows calls are being made to the server but react isn't fetching or displaying data
any help on how to solve this problem would be appreciated as I currently don't know what I did wrong
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
I am working on react project, In my project I am trying to get data from backend my Api is also working fine by I am unable to display data in front end in table format. So please help me to display data in table format.
This is my code
import React, { Component } from 'react';
import './Profiles.css';
import axios from 'axios';
export default class Profiles extends Component {
constructor(props) {
super(props)
this.state = {
products: []
}
}
async getProfiles() {
try {
const res = await axios.get('http://localhost:5000/api/products');
this.setState( { products: res.data } )
} catch (error) {
console.log(error)
}
}
render() {
return (
<div className='container'>
<div className='row'>
<div className='col-12'>
<table className="table table-bordered">
<thead>
<tr>
<th>Brand</th>
<th>Price</th>
<th>Replacement</th>
<th>Discount</th>
<th>Edit</th>
<th>Delete</th>
</tr>
</thead>
<tbody>
{this.state.jobs.map(currentValue =>
<tr>
<td>{currentValue.name}</td>
<td>{currentValue.position}</td>
<td>{currentValue.location}</td>
<td>{currentValue.salary}</td>
<td>
<button className='btn btn-primary'>Edit</button>
</td>
<td>
<button className='btn btn-danger'>Delete</button>
</td>
</tr>
)}
</tbody>
</table>
import React, { Component } from 'react';
import './Profiles.css';
import axios from 'axios';
export default class Profiles extends Component {
constructor(props) {
super(props)
this.state = {
jobs: []
}
}
componentDidMount() {
this.getProfiles()
}
async getProfiles() {
try {
const res = await axios.get('http://localhost:7500/api/registration');
this.setState( { jobs: res.data } )
} catch (error) {
console.log(error)
}
}
render() {
return (
<div className='container'>
<div className='row'>
<div className='col-12'>
<table className="table table-bordered">
<thead>
<tr>
<th>Name</th>
<th>Position</th>
<th>Location</th>
<th>Salary</th>
<th>Edit</th>
<th>Delete</th>
</tr>
</thead>
<tbody>
{this.state.jobs.map(currentValue =>
<tr>
<td>{currentValue.name}</td>
<td>{currentValue.position}</td>
<td>{currentValue.location}</td>
<td>{currentValue.salary}</td>
<td>
<button className='btn btn-primary'>Edit</button>
</td>
<td>
<button className='btn btn-danger'>Delete</button>
</td>
</tr>
)}
</tbody>
</table>
I am working on a react project I am trying to display data in td, the data is coming from backend and that data is coming in console. But I am not able to display data in table.
For this project I am using functional Component
This is my Child.js
import React, { useState, useEffect } from 'react';
import axios from 'axios';
export default function Child() {
const [oldEmployData, newEmployData] = useState([])
async function getEmploysData() {
try {
const response = await axios.get('http://localhost:1000/api/employList');
newEmployData(response.data);
console.log(response.data)
} catch(error) {
console.log(error)
}
}
useEffect(() => {
getEmploysData()
}, [])
return (
<div className='container'>
<div className='row'>
<div className='col-12'>
<table className="table table-bordered">
<thead>
<tr>
<th>Employ Name</th>
<th>Employ Age</th>
<th>Employ Stream</th>
<th>Employ Address</th>
<th>Edit</th>
<th>Delete</th>
</tr>
</thead>
<tbody>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td>
<button className='btn btn-primary'>Edit</button>
</td>
<td>
<button className='btn btn-danger'>Delete</button>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
)
}
If I am clear please put a comment
Assuming your axios request is responding with a valid JSON array, you can render that data directly into your table via Array#map() by extending your render logic as shown below:
<tbody>
{data.map(item =>
<tr key={item.id}>
{/* assuming each item in JSON array has firstName, lastName, email
and password fields */}
<td>{item.firstName}</td>
<td>{item.lastName}</td>
<td>{item.email}</td>
<td>{item.password}</td>
{/* suppose you have editItem() and deleteItem() defined, these
can be invoked (during click event) for each item like this */}
<td>
<button className="btn btn-primary"
onClick={() => editItem(item)}>Edit</button>
</td>
<td>
<button className="btn btn-danger"
onClick={() => deleteItem(item)}>Delete</button>
</td>
</tr>)}
</tbody>
An important point to note is that each <tr> element being mapped must have a key prop supplied with a value that is unique to the item being rendered/mapped. With that in mind, the assumption being made above is that each item in the data array has a unique id.
Suppose json data like this
let data = [
{id:1,name:'One'},
{id:2,name:'Two'},
{id:3,name:'Three'}
]
Iterate like this
{data.map(d=>
<tr key={d.id}>
<td>{d.name}</td>
<td>{}</td>
<td>{}</td>
<td></td>
<td><button className='btn btn-primary' onClick={()=>handleEdit(d.id)>Edit</button></td>
<td><button className='btn btn-danger' onClick={()=>handleDelete(d.id)}>Delete</button></td>
</tr>
)}
I could render the herader's table users through for exemple: {user[name]}. But I couldn't render the header itself who is the [name] for example rendering: name of Leanne Graham. Can anyone help me with this?
import React from 'react'
const Users= ({ users}) => {
return (
<div>
{users.map((user,index) => (
<div key={index}>
<div className="container smcontainer d-flex justify-content-start">
<div className="row">
<div className="col-md-12">
<table className="table table-striped">
<thead>
</thead>
<tbody>
<tr>
<td className=""> {user['id']} </td>
<td className=""> {user['name']} </td>
<td className=""> {user['username']} </td>
<td className=""> {user['email']} </td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
))}
</div>
)}
export default Products
This is the App component
class App extends Component {
constructor(props){
super(props)
this.state= {
users: [],
}
}
async componentDidMount() {
const url = ('https://jsonplaceholder.typicode.com/users')
const response = await fetch (url)
const data = await response.json()
this.setState({users: data.itemsList})
console.log({users: data.itemsList})
}
render() {
return (
<Users users = {this.state.users} />
)
}
}
export default App;
When you map over an array, whatever you return is returned each time for every element in the array. This code will create a whole new table for each user.
I think what you want to do is define your column headers separately from your map call and then map over the array to generate the rows:
const columns = ["ID", "Name", "Username", "Email"];
...
<div>
<div className="container smcontainer d-flex justify-content-start">
<div className="row">
<div className="col-md-12">
<table className="table table-striped">
<thead>
{columns.map(c => <th>{c}</th>)}
</thead>
<tbody>
{users.map((user, index) => (
<tr>
<td className=""> {user['id']} </td>
<td className=""> {user['name']} </td>
<td className=""> {user['username']} </td>
<td className=""> {user['email']} </td>
</tr>
))}
</tbody>
</table>
</div>
</div>
</div>
</div>
I made a Codepen demonstrating both ways, but to me the first one makes much more sense.
That should give you what you want.
<thead>
{user['name']}
<thead/>
If you want to take the first name of Leanne Graham, you can do:
<thead>
{user['name'].split(" ")[0]}
<thead/>
I have table so I want to retrieve key/value of specific row in which button was clicked.
componentDidMount() {
let com = this;
firebase
.database()
.ref()
.child("bills")
.once("value", snap => {
let items = [];
snap.forEach(childD => {
items.push({
balance: childD.val().balance,
bill_num: childD.val().bill_num,
date: childD.val().date,
key: childD.val().key,
name: childD.val().name,
total: childD.val().total
});
});
Array.prototype.push.apply(com.state.products, items);
com.setState({
products: com.state.products
});
});
}
open = e => {
e.preventDefault();
console.log("kal" + this.state.value);
};
handleChange=event=>{
this.setState({value: event.target.value});
}
render() {
return (
<table className="table table-striped">
<thead>
<tr>
<th scope="col">Bill number</th>
<th scope="col">Name</th>
<th scope="col">Date</th>
<th scope="col">Total</th>
<th scope="col">Balance</th>
<th scope="col">Delete</th>
<th scope="col">Open bill</th>
</tr>
</thead>
<tbody>
{console.log(this.state.products)}
{this.state.products.map((value, key) => (
<tr key={value.key}>
<th scope="row">{value.bill_num}</th>
<td>{value.name}</td>
<td>{value.date}</td>
<td>{value.total}</td>
<td>{value.balance}</td>
<td>
<form onSubmit={this.returnOrder}>
<input value={value.key} type="hidden" />
<button className="btn btn-danger" type="submit">
Return
</button>
</form>
</td>
<td>
<form onSubmit={this.open}>
<input value={value.key} onChange={this.handleChange} ref={ eKey => (this.inputeKey = eKey)} />
<button className="btn btn-info" type="submit">
Open
</button>
</form>
</td>
</tr>
))}
</tbody>
</table>
</div>
) : (
<Printout
keya={{
key: this.props.keyas
}}
/>
)}
);
}
}
Typically, tables in React are made from several components: whole table, row and for example buttons in row. So in table you place array of rows. Each row has it's child buttons. So you can send props to RowButtons child with information about clicked row.
I am doing a fetch and storing the result in my state "data", then i am sending this "data" to the function "Showingmovies" , there i am using table tag to align my layout . But the elements are not being rendered from the "Showingmovies" function, i have found that the props are being succesfully passed to the function still it is not rendering.
Below is my complete code -
import React, { Component } from 'react'
function Showingmovies(props){
console.log("in showingmovies",props.mov)
return(
<table>
<tbody>
{props.mov.results.map((mv) =>{
<tr>
<td>
<p>image here</p>
</td>
<td>
{mv.original_title}
<p>{mv.overview}</p>
</td>
</tr>
})}
</tbody>
</table>
)}
export default class movie extends Component {
constructor(){
super()
this.state={
data: [],
}
}
componentWillMount(){
fetch("https://api.themoviedb.org/3/search/movie?
api_key=ab85c167dc8f5538f5b6e08f01923243&query=J")
.then((res) =>res.json())
.then((data) => this.setState({
data: data,
}))
}
render() {
return (
<div>
<p>hi i will show you movies</p>
{this.state.data.length !== 0 ?
<Showingmovies mov = {this.state.data}/>:null}
</div>
)
}
}
You need to add return in the map method as
function Showingmovies(props){
return(
<table>
<tbody>
{props.mov.results.map((mv) =>{
return (
<tr>
<td>
<p>image here</p>
</td>
<td>
{mv.original_title}
<p>{mv.overview}</p>
</td>
</tr>
)
})}
</tbody>
</table>
)}
Problem is return
Solution
Whenever you use map you must use return if you use `{} like
{props.mov.results &&
props.mov.results.map(mv => {
return <tr>
<td>
<p>image here</p>
</td>
<td>
{mv.original_title}
<p>{mv.overview}</p>
</td>
</tr>;
})}
and if you are not don't want to return then remove {} like
{props.mov.results && props.mov.results.map(mv =>
<tr>
<td>
<p>image here</p>
</td>
<td>
{mv.original_title}
<p>{mv.overview}</p>
</td>
</tr>)
}
codeSandbox