Why is my data not displaying in the table in react - reactjs

Does anyone know why my data isn't displaying, it console.logs 'x[0]', 'x[1]', 'x[2]', and 'x[3]' fine in my return statement. I'm pretty new to react and programming in general so I have no idea why this doesn't work.
I would just expect it to fill the rows of the table like the 2 I've manually coded in.
import React, { useState, useEffect } from 'react'
import "./stylesheets/oddsmatcher-table.css"
const App = () => {
const [wow, setWow] = useState([])
useEffect(() => {
fetch(DATA)
.then(res => res.json())
.then(data => {
const newData = data.data.slice(0, 10)
const k = newData.map(x => {
return [x.date, x.event_name, x.bookmaker_name, x.exchange]
})
setWow(k)
console.log(k)
})
}, [])
return(
<table>
<tbody>
<tr>
<th>Date</th>
<th>Event</th>
<th>Bookie</th>
<th>Exchange</th>
</tr>
<tr>
<td>25-09-2020</td>
<td>Man United vs Liverpool</td>
<td>Bet365</td>
<td>Smarkets</td>
</tr>
<tr>
<td>26-09-2020</td>
<td>Arsenal vs Man City</td>
<td>Coral</td>
<td>Betfair Exchange</td>
</tr>
{wow.forEach(x => {
return(
<tr>
<td>{x[0]}</td>
<td>{x[1]}</td>
<td>{x[2]}</td>
<td>{x[3]}</td>
</tr>
)
})}
</tbody>
</table>
)
}
export default App

Update: Try switching your wow.forEach to this:
{wow.map((x, index) => {
return (
<tr key={index}>
{x.map((dataPiece) => (
<td key={dataPiece}>{dataPiece}</td>
))}
</tr>
);
})}
Here's the Codesandbox I was using to test. I replaced your async fetch with a global variable with what I think your wow data looks like:
https://codesandbox.io/s/suspicious-glitter-mf0tg?fontsize=14&hidenavigation=1&theme=dark
Let me know if that works. If it doesn't, can you post an example of what your fetched data looks like?

Related

fetching data not showing in table in react

I am create a table and fetching data using axios but in the table I am not able to print the data when I check data is printing in browser but not able to print the particular data to a table format so what should be change in my code?
import { useEffect, useState } from "react";
import "bootstrap/dist/css/bootstrap.min.css";
import { Table } from "react-bootstrap";
import axios from "axios";
export default function App() {
const [user, setUser] = useState([]);
useEffect(() => {
axios
.get("https://jsonplaceholder.typicode.com/users", (req, res) => {
res.json();
})
.then((data) => setUser({ ...user, data }))
.catch((error) => console.error(error));
});
return (
<div className="App">
<h3 className="text-primary">User List</h3>
<Table
variant="danger"
striped
bordered
hover
className="shadow-lg text-center"
>
<thead>
<tr>
<th>id</th>
<th>Name</th>
<th>UserName</th>
<th>Email</th>
</tr>
</thead>
<tbody>
{user?.data?.length > 0 &&
user.data.map((user) => {
return (
<tr key={user.id}>
<td>{JSON.stringify(user.data["data"].id)}</td>
<td>{JSON.stringify(user.data["data"].name)}</td>
<td>{JSON.stringify(user.data["data"].username)}</td>
<td>{JSON.stringify(user.data["data"].email)}</td>
</tr>
);
})}
</tbody>
</Table>
{/* <div>{JSON.stringify(user.data["data"])}</div> */}
</div>
);
}
for example
import { useEffect, useState } from "react";
import "bootstrap/dist/css/bootstrap.min.css";
import { Table } from "react-bootstrap";
import axios from "axios";
export default function App() {
const [user, setUser] = useState([]);
useEffect(() => {
axios
.get("https://jsonplaceholder.typicode.com/users")
.then((res) => {
setUser(res.data);
})
.catch((error) => console.error(error));
}, []);
return (
<div className="App">
<h3 className="text-primary">User List</h3>
<Table
variant="danger"
striped
bordered
hover
className="shadow-lg text-center"
>
<thead>
<tr>
<th>id</th>
<th>Name</th>
<th>UserName</th>
<th>Email</th>
</tr>
</thead>
<tbody>
{user?.length > 0 &&
user.map((userData) => {
return (
<tr key={userData.id}>
<td>{userData.id}</td>
<td>{userData.name}</td>
<td>{userData.username}</td>
<td>{userData.email}</td>
</tr>
);
})}
</tbody>
</Table>
{/* <div>{JSON.stringify(user)}</div> */}
</div>
);
}
Replace the useEffect code as follow.
useEffect(() => {
axios
.get("https://jsonplaceholder.typicode.com/users")
.then((data) => setUser({ ...user, data }))
.catch((error) => console.error(error));
}, []);
You already know that calling this api will give you an array of users so you can initialise the state as empty array as:
const [users, setUsers] = useState([]);
and when you are using axios then you don't have to use res.json(). axios will do it for you out of the box.
axios
.get("https://jsonplaceholder.typicode.com/users")
.then(({ data }) => setUsers(data))
.catch((error) => console.error(error));
so, after getting data using get method of axios it will return you a promise and you can get data from its data property that is passed an first args. You can directly set state which will be an array of objects.
.then(({ data }) => setUsers(data))
Here I've destructed the object to get only the data property.
Since users will be an array of objects, so you don't have to do any check. You can directly use user.id to get the respective property.
Codesandbox link
export default function App() {
const [users, setUsers] = useState([]);
useEffect(() => {
axios
.get("https://jsonplaceholder.typicode.com/users")
.then(({ data }) => setUsers(data))
.catch((error) => console.error(error));
}, []);
return (
<div className="App">
<h3 className="text-primary">User List</h3>
<Table
variant="danger"
striped
bordered
hover
className="shadow-lg text-center"
>
<thead>
<tr>
<th>id</th>
<th>Name</th>
<th>UserName</th>
<th>Email</th>
</tr>
</thead>
<tbody>
{users.map((user) => {
return (
<tr key={user.id}>
<td>{user.id}</td>
<td>{user.name}</td>
<td>{user.username}</td>
<td>{user.email}</td>
</tr>
);
})}
</tbody>
</Table>
{/* <div>{JSON.stringify(user.data["data"])}</div> */}
</div>
);
}

How can I fix error when trying to render data?

I'm making an application to render the data in a table dynamically. But this error appears: "getUserData.map is not a function".
I didn't find any apparent errors, how can I solve this problem?
API: link
console: console
useRequestData:
import axios from "axios"
import { useEffect, useState } from "react"
export const useRequestData = (initialState, url) => {
const [data, setData] = useState(initialState)
useEffect(() => {
axios.get(url)
.then((res) => {
setData(res.data)
})
.catch(() => {
alert('Erro')
})
}, [url])
return data
}
Component:
import { Container, TableHeader } from "./styles"
import plusImg from "../../assets/plus.png"
import minusImg from "../../assets/minus.png"
import editImg from "../../assets/edit.png"
import { useRequestData } from "../hooks/useRequestData"
import { baseUrl } from "../../services/api"
export const UsersTable = () => {
const getUserData = useRequestData([], baseUrl)
return (
<Container>
<table>
<thead>
<tr>
<th>
<img src={plusImg} alt="" />
</th>
<th>Nome</th>
<th>Endereço</th>
<th>Cidade</th>
<th>UF</th>
<th>Telefone</th>
<th>E-mail</th>
</tr>
</thead>
<tbody>
{getUserData.map((user) => (
<tr key={user.TECL_ID}>
<tr>
<td>
<img src={minusImg} alt="" />
</td>
<td>
<img src={editImg} alt="" />
</td>
</tr>
<td>{user.TECL_NOME}</td>
<td>{user.TECL_ENDERECO}</td>
<td>{user.TECL_CIDADE}</td>
<td>{user.TECL_UF}</td>
<td>{user.TECL_TELEFONE}</td>
<td>fulano#gmail.com</td>
</tr>
))}
</tbody>
</table>
</Container>
)
}
Few things, inside your custom hook, create a function to get the data outside of the useEffect and THEN, run it inside useEffect.
Now, you have to return your data state from your custom hook in order to use it, so... At the bottom of your custom hook (outside of useEffect) write this:
return { data };
Now in your Component you could do something like this:
const { data } = useRequestData([], baseUrl)
And that's pretty much it, let me know if that helps.

React.js using onclick function to render a table

I have an array of objects coming from two different api. the first api I am converting it to a bullet point using
tag. and the second api should be converted to a table using tag. What I want to do is whenever I click on the bullet point it should show the table with the appropriate data. I was successfully able to get the data from both apis.
The main problem I am having is, the onClick function. First, after mapping the bullet point, the onclick function treat it as one gigantic click button. they are not seperated. Second, when I tried to hard code it , since they are only 8 bullet points. I was not able to get the data on a table.
I start coding just about a month and half ago, I have been trying everything I know for the last five days. At this point I ran out of ideas.
note that this is an example of only the fisrt table i have 8 more.
Please Help me guys thank you!
import React, { useEffect, useState } from 'react';
import './App.css';
const App = () => {
const reqMenu = "fake link";
const reqDescription = "fake link";
const [recipes, setRecipes] = useState([]);
const [description, setDescription] = useState([])
useEffect(() => {
getReq()
getDesc()
},[]);
const getReq = async () => {
const response = await fetch(reqMenu);
const data = await response.json()
setRecipes(data)
// console.log(data)
};
const getDesc = async () => {
const response= await fetch(reqDescription);
const data = await response.json()
setDescription(data)
// console.log(data)
}
const ss = description.filter((e) => (e.short_name.startsWith("SS")))
return (
<div className="App">
<h1>Menu Categories</h1>
<div>
<ul>
{recipes.map((recipe ,id, index) => (
<li key={id} onClick={() =>
{if(index[0] = recipes[0]["short_name"]){
return <table>
<tr>
<th>Name</th>
<th>Description</th>
</tr>
{ss.map((s) =>{
<tr key={id}>
<td>{s.name}</td>
<td>{s.description}</td>
</tr>
})}
</table>
}}}>
{recipe.name}-({recipe.short_name})
</li>
))}
</ul>
</div>
</div>
);
}
export default App;
onClick doesn't accept a return value. What you want to do is conditionally render the components based on state from the onClick.
.map also does not have an id argument.
Also, JavaScript comparison is done using == or ===. Using a single = will do assignment, not comparison.
const initialListState = recipes.map(() => false);
const [listState, setListState] = useState(initialListState);
return (
<div className="App">
<h1>Menu Categories</h1>
<div>
<ul>
{recipes.map((recipe, index) => (
<li
key={index}
onClick={() => {
const newListState = [...listState];
newListState[index] = true;
setListState(newListState);
}
>
<table>
<thead
<tr>
<th>Name</th>
<th>Description</th>
</tr>
</thead>
<tbody>
{listState[index] && (
ss.map((s, sindex) => (
<tr key={sindex}>
<td>{s.name}</td>
<td>{s.description}</td>
</tr>
)
}
</tbody>
</table>
{recipe.name}-({recipe.short_name})
</li>
}
</ul>
</div>
</div>
);

Can someone explain in detail or provide a video link that can help me understand how to sort a mongodb in react

I saw different versions but honestly they make no sense. I tried to implement them so I can understand it myself but I didn't know where I should put it at. does it go in my view main.js file or what file and then where in that file does it go.
import React, { useState, useEffect } from 'react'
import axios from 'axios'
import { Link } from '#reach/router'
const Main = props => {
const [pets, setPet] = useState()
useEffect((req, res) => {
axios.get(`http://localhost:8000/api/users`)
.then(res => {// does the sort go here
// console.log(res.data.users)
setPet(res.data.users)
})
}, [])
// would the sort go before or in here ?
return (
<div>
These pets need a home: do you know any other pets Add Pet
<table className='table table-striped table-dark '>
<thead className="">
<tr>
<th>Name</th>
<th>Type</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{
pets ?
pets.map((pet, i) => {
return (
<tr key={i}>
<td>{pet.pet_name}</td>
<td>{pet.pet_type}</td>
<td><Link to={`/viewpet/${pet._id}`}>Detail</Link> | <Link to={`/update/${pet._id}`}>Edit</Link></td>
</tr>
)
})
: ''
}
</tbody>
</table>
</div>
)
}
export default Main;
Thanks to #hellogoodnight and some help to other folks to help me understand what you were saying.
the answer was what you said :)
setPet(res.data.users.sort((a, b) => a.pet_name < b.pet_name ? -1 : 1)

How can I pass props to another components with in reactjs

I'm trying to pass product data from AllProducts component to Product component.
AllProducts.jsx: is showing all the products I have and Product.jsx will show specific product and how can I pass data to Product.jsx?
Here is my AllProducts.jsx:
const AllProducts = (props) => {
const [products, setProducts] = useState([]);
const getProductsAPI = () => {
axios
.get("http://localhost:8000/api/products")
.then((res) => {
setProducts(res.data);
getProductsAPI();
})
.catch((err) => {
console.log(err);
});
};
useEffect(() => {
getProductsAPI();
}, [props]);
return (
<div>
<table className="table table-bordered table-hover">
<thead>
<tr>
<th>#</th>
<th>Title</th>
<th>Action</th>
</tr>
</thead>
<tbody>
{products.map((product, i) => (
<tr key={i}>
<th scope="row">{i}</th>
<td>{product.title}</td>
<td>
<Link to={`/products/${product._id}`}> View </Link>
</td>
</tr>
))}
</tbody>
</table>
</div>
);
};
and here is my Product.jsx:
const Product = (props) => {
return (
<div className="container">
<h4>{props.product.title}</h4>
</div>
);
};
export default Product;
Here is my project github if you want to look at all the code I have: https://github.com/nathannewyen/full-mern/tree/master/product-manager
If the data is fully loaded for each product in AllProducts, and you don't want to make another API call by product id in the Product component, in this case, you don't have to use a route link to view Product, just make a conditional rendering to show Product component inside AllProducts component. pseudo-code as below,
const [showProduct, setShowProduct] = useState(false);
const [currentProduct, setCurrentProduct] = useState();
const showProduct = (product) => {
setShowProduct(true);
setCurrentProduct(product);
}
<tbody>
{products.map((product, i) => (
<tr key={i}>
<th scope="row">{i}</th>
<td>{product.title}</td>
<td>
<button type="button" onclick = {showProduct(product)}>View</button>
</td>
</tr>
))}
</tbody>
return (showProduct ? <Product /> : <AllProucts/>)
If you also need to make another API call to get extra data for each product, then use the router link but perhaps you can not pass props.

Resources