I have objects, in the database. I want to grab the userId using axios, but when I tried to console.log() it. It shows undefined. hen I hardcoded it and targeted it by array, it shows.
How can I console log all of userId? I would like to grab it so I can use it as an endpoint for my database
const res = await userRequest.get('user/find/'+userId)
I want to grab the userId only.
import React, { useEffect, useState } from 'react'
import { format } from 'timeago.js'
import { userRequest } from '../../requestMethod'
import './Widgetlg.css'
const WidgetLg = () => {
const Button = ({ type }) => {
return <button className={'widgetLgButton ' + type}>{type}</button>
}
const [orders, setOrders] = useState([])
const [users, setUsers] = useState([])
useEffect(() => {
const getOrders = async () => {
//this is just a shorcut api
try {
const res = await userRequest.get('orders')
setOrders(res.data)
console.log(res.data?.userId)
console.log(res.data)
console.log(res.data[0].userId)
} catch (error) {
console.log(error)
}
}
getOrders()
}, [])
useEffect(() => {
const getUsername = async () => {
try {
const res = await userRequest.get('user/find/')
setUsers(res.data)
} catch (error) {}
}
getUsername()
}, [])
return (
<div className="widgetLg">
<h3 className="widgetLgTitle">Latest Transactions</h3>
<table className="widgetTable">
<tr className="widgetLgTr">
<th className="widgetLgTh">Customer</th>
<th className="widgetLgTh">Date</th>
<th className="widgetLgTh">Amount</th>
<th className="widgetLgTh">Status</th>
</tr>
{orders.map((order) => (
<tr className="widgetLgTr">
<td className="widgetLgUser">
<span className="WidgetLgName"> **I want here to show the username** </span>
</td>
<td className="widgetLgDate"> {format(order.createdAt)} </td>
<td className="widgetLgAmmount">P {order.amount} </td>
<td className="widgetLgStatus">
<Button type={order.status} />
</td>
</tr>
))}
</table>
</div>
)
}
export default WidgetLg
You could try something like this if I understand you correctly
const userIdsArray = res.data.map(d => d.userId);
console.log(userIdsArray);
res.data is an array. To log all elements, you could just iterate over them:
res.data.forEach(el => console.log(el.userId));
The reason that console.log(res.data) gives undefined is that the array itself doesn't have a userId field, only the elements of the array do.
Related
I'm fetching data from an endpoint, and if I use a console.log(data) it shows it correctly.
Image of my array
I only want data.data, so I use console.log(data.data) and apparently It show correctly what I need.
Data that I need
My problem is that I'm trying to show all clients in a table, but it only shows one of them.
This is my code:
import { useEffect, useState } from "react";
function Activity() {
function LoadActivity() {
fetch("https://localhost:7079/client/listClient")
.then((response) => {
return response.json()
})
.then((data) => {
setActivity([data.data])
});
}
const [actividad, setActivity] = useState([]);
useEffect(() => {
LoadActivity();
}, []);
return (
<div>
<h1>Cliente</h1>
<table>
<thead>
<tr>
<th>Id</th>
<th>name</th>
<th>Email</th>
</tr>
</thead>
<tbody>
{
actividad.map((client, i )=>(
<tr key={client[i].id}>
<td>{client[i].name}</td>
<td>{client[i].Email}</td>
<td>{client[i].id}</td>
</tr>
))
}
</tbody>
</table>
</div>
);
}
export default Activity;
And this is how it displays:
What is displayed
I tried to do it like this question 3 years ago.
I'm very new with React, and I don't know what I'm missing.
This is how I resolved it
const [equipo, setEquipo] = useState([]);
useEffect(() => {
obtenerDatos();
}, []);
const obtenerDatos = async () =>{
const datos = await fetch('https://localhost:7079/cliente/listarClientes')
const clientes = await datos.json()
setEquipo(clientes.data)
}
I am trying to sort the HTML table, but getting the error. Is there anything I am doing wrongly?
I want to able to sort ascending and descending. I am using useMemo. To make it, I am sorting on search return called searchPosts and I have sortType and setSortType defined in my useState.
import React, {useState, useEffect, useMemo} from 'react'
import '../css/about.css';
import Pagination from '../components/Pagination'
function About() {
const [userData, setUserData] = useState([]);
const [loading , setLoading] = useState(false);
const [currentPage, setCurrentPage] = useState(1);
const [postsPerPage, setPostsPerPage] = useState(5);
const [search, setSearch] = useState("");
const [sortType, setSortType] = useState('asc');
async function getData()
{
let response = await fetch('https://api.github.com/users');
let data = await response.json();
return data;
}
//call getData function
getData()
.then(data => console.log(data)
);//
useEffect(() => {
setLoading(true)
getData()
.then(
data => {
setUserData(data) }
)
.catch(error => {
console.log(error);
})
}, [])
// Get current posts
const indexOfLastPost = currentPage * postsPerPage;
const indexOfFirstPost = indexOfLastPost - postsPerPage;
const currentPosts = userData.slice(indexOfFirstPost, indexOfLastPost);
// changd page
const paginate = (pageNumber) => setCurrentPage(pageNumber);
// Search Table
const handleFilterChange = e => {
setSearch(e.target.value)
}
// for search
function DataSearch(rows) {
const columns = rows[0] && Object.keys(rows[0]);
return rows.filter((row) =>
columns.some((column) => row[column].toString().toLowerCase().indexOf(search.toLowerCase()) > -1)
);
}
const searchPosts = DataSearch(currentPosts);
// **for Sorting**
const sorted = useMemo(() => {
if(!sortType) return searchPosts;
return searchPosts.slice().sort((a, b) => a[searchPosts].localeCompare(b[searchPosts]));
}, [searchPosts, sortType]);
return (
<div className="container">
<div>
<div>
<input value={search} onChange={handleFilterChange} placeholder={"Search"} />
</div>
<div> {loading }</div>
<table>
<thead>
<tr>
<th>id</th>
<th>avatar_url</th>
<th>events_url</th>
<th>followers_url</th>
<th>following_url</th>
<th>gists_url</th>
<th>gravatar_id</th>
<th>html_url</th>
<th>
login
<a onClick={() => setSortType("login")}> Sort by Login</a>
</th>
<th>node_id</th>
<th>organizations_url</th>
<th>received_events_url</th>
<th>repos_url</th>
<th>site_admin</th>
<th>starred_url</th>
<th>subscriptions_url</th>
<th>type</th>
<th>url</th>
</tr>
</thead>
<tbody>
{
sorted.map((item, index) => (
<tr key={index}>
<td>{item.id}</td>
<td>{item.avatar_url}</td>
<td>{item.events_url}</td>
<td>{item.followers_url}</td>
<td>{item.following_url}</td>
<td>{item.gists_url}</td>
<td>{item.gravatar_id}</td>
<td>{item.html_url}</td>
<td>{item.login}</td>
<td>{item.node_id}</td>
<td>{item.organizations_url}</td>
<td>{item.received_events_url}</td>
<td>{item.repos_url}</td>
<td>{item.site_admin}</td>
<td>{item.starred_url}</td>
<td>{item.subscriptions_url}</td>
<td>{item.type}</td>
<td>{item.url}</td>
</tr>
))
}
</tbody>
</table>
<Pagination postsPerPage={postsPerPage} totalPosts={userData.length} paginate={paginate} />
</div>
</div>
)
}
export default About
I saw from stackoverflow the sorting example and I copied it to work with the code I have already.
First locate this line
const [sortType, setSortType] = useState('asc');
change it to
const [sortType, setSortType] = useState(null);
Now go to, replace with the code below
const sorted = useMemo(() => {
if(!sortType) return searchPosts;
return searchPosts.slice().sort((a, b) => a[sortType].localeCompare(b[sortType]));
}, [searchPosts, sortType]);
The mistake you did was the searchPosts instead of sortType
Then in your table, go
<th>
login
<a onClick={() => setSortType("login")}> Sort by Login</a>
</th>
You shouldn't have any error.
I'm trying to display these data that is stored in countries list, however, it is result in me getting nothing in my Table. The problem is most likely caused by the Table not rerendering correctly, I tried to use useEffect on line 14 to print out the length of the list, and I did get the correct result. Any hint would be appreciated!
import React, { useState, useEffect } from "react";
import getData from "../Hooks/getData";
import Table from "react-bootstrap/Table";
const Lists = () => {
const [countries, setCountries] = useState([]);
if (countries.length === 0) {
getData().then((data) => {
setCountries(data.data.Countries);
});
}
useEffect(() => {
console.log(countries.length);
});
const getInfo = () => {
countries.map((country) => {
return (
<tr>
<td>{country.Country}</td>
<td>{country.NewConfirmed}</td>
<td>{country.TotalConfirmed}</td>
</tr>
);
});
};
return (
<Table striped bordered hover>
<thead>
<tr>
<th>Country Name</th>
<th>New Confirmed</th>
<th>Total Confirmed</th>
</tr>
</thead>
<tbody>{getInfo()}</tbody>
</Table>
);
};
export default Lists;
Your getInfo does not return anything.
Either use the implicit return, by not using {} around the funtion body, or explicitly use the return statement
const getInfo = () => countries.map((country) => {
return (
<tr>
<td>{country.Country}</td>
<td>{country.NewConfirmed}</td>
<td>{country.TotalConfirmed}</td>
</tr>
);
});
or
const getInfo = () => {
return countries.map((country) => {
return (
<tr>
<td>{country.Country}</td>
<td>{country.NewConfirmed}</td>
<td>{country.TotalConfirmed}</td>
</tr>
);
});
};
sample image of page so far
Please see the above image. I'm wanting to be able to remove the string in the "skill" column when it is deleted after clicking the "Delete" button on the right. I can delete an Employee using filter() with the Delete button on the left. This removes the entire row from the DOM, which is great, but I would like the Delete button on the right to simply remove the content from the Skill(s) column for that particular employee.
I have tried doing something similar in the deleteSkill() function, but I am not sure how to remove the content of the Skill(s) column without deleting the entire row. The issue lies in my setList() function within my deleteSkill() function. Any ideas would be greatly appreciated.
Here is the code:
import React, { Fragment, useEffect, useState } from 'react';
const List = () => {
const [list, setList] = useState([]);
//DELETE Employee by ID
const deleteEmployee = async (id) => {
try {
const deleteEmployee = await fetch(`http://localhost:5000/employees/${id}`, {
method: "DELETE"
});
setList(list.filter(item => item.employee_uuid !== id));
} catch (err) {
console.error(err.message)
}
};
//DELETE Skill by ID
const deleteSkill = async (id) => {
try {
const deleteSkill = await fetch(`http://localhost:5000/employees/${id}/skills`, {
method: "DELETE"
});
setList(list.filter(item => item.summary !== id));
} catch (err) {
console.error(err.message)
}
};
const getList = async () => {
try {
const response = await fetch("http://localhost:5000/employees")
const jsonData = await response.json();
setList(jsonData);
} catch (err) {
console.error(err.message);
}
};
useEffect(() => {
getList();
}, []);
console.log(list);
return (
<Fragment>
{" "}
<h1 class="text-center">Employee Skills Tracker</h1>
<table class="table mt-5 text-center">
<thead>
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th></th>
<th></th>
<th>Skill(s)</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
{list.map(item => (
<tr key={item.employee_uuid}>
<td>{item.firstname}</td>
<td>{item.lastname}</td>
<td>Edit</td>
<td><button className="btn btn-danger" onClick={() => deleteEmployee(item.employee_uuid)}>Delete</button></td>
<td>{item.summary}</td>
<td>Edit</td>
<td><button className="btn btn-danger" onClick={() => deleteSkill(item.employee_uuid)} >Delete</button></td>
</tr>
))}
</tbody>
</table>
</Fragment>
);
};
export default List;
Instead of using list.filter(), use list.map(). The key is that you want to return a 1:1 list of modified elements, not a list without certain elements.
If you want to remove the summary for just a specific employee, I'd recommend
setList(list.map(item => {
if (item.id !== id) {
return item; // not the right employee, pass it through
}
let newItem = {...item};
delete newItem.summary;
return newItem;
}));
It's more complex, because you have to explicitly return what you want, but it's also what you're asking for.
I am learning REST API. I am using the react app for front end and backend for Node js and express server. For API I am using REST API. I am using MongoDB for the database. I successfully display all the data to the browser. I can able to search the data. Now I want to delete the data. I don't know how to delete data from REST API endpoint. I will be really glad if someone help me out. I tested my backend by using Postman. Everything works fine as expected.
This is my backend delete end point
app.delete("/students/:id", async (req, res, next) => {
const id = req.params.id;
try {
student
.remove({ _id: id })
.exec()
.then(data => {
res.json(data);
});
} catch (error) {
console.log(error);
}
});
I export my API END points to React js
export async function deleteStudent(id) {
const response = await fetch(`/students/${id}`, {
method: "DELETE"
});
return response.json();
}
This is the main component where I want to delete the data
import React, { useState, useEffect } from "react";
import { logEntry } from "../Api/Api";
import { deleteStudent } from "../Api/Api";
function Datatable() {
const [total, settotal] = useState([]);
const [searchItem, setsearchItem] = useState({
item: ""
});
const [data, setdata] = useState([]);
const handleChange = e => {
setsearchItem({ item: e.target.value });
};
const getEntries = async () => {
const logEntries = await logEntry();
console.log(logEntries);
settotal(logEntries.count);
setdata(logEntries.students);
};
const nameFilter = data.filter(list => {
return list.name.toLowerCase().includes(searchItem.item.toLowerCase());
});
const deleteData = async id => {
await deleteStudent(id);
};
useEffect(() => {
getEntries();
}, []);
return (
<div>
<div style={{ paddingLeft: "800px" }}>
<input
placeholder="Search student"
onChange={handleChange}
style={{ width: "200px", height: "30px" }}
/>
</div>
<p>Total student: {total} </p>
<table>
<thead>
<tr>
<th>Name</th>
<th>City</th>
<th>Address</th>
<th>Phone</th>
<th>Email</th>
</tr>
</thead>
<tbody>
{nameFilter === "" ? (
<p>Student not found</p>
) : (
nameFilter.map(list => {
return (
<tr>
<td>{list.name}</td>
<td>{list.city}</td>
<td>{list.address}</td>
<td>{list.phone}</td>
<td>{list.email}</td>
<td>
<a
className="waves-effect red btn-small"
onClick={() => deleteData(list.id)}
>
Delete
</a>
</td>
</tr>
);
})
)}
</tbody>
</table>
</div>
);
}
export default Datatable;
I don't know, Am I doing?
This looks like a great start! I'm operating on the understanding that you need to somehow pass the id of the student you want to delete into the URL in deleteStudent() from the 'DELETE' button in your <DataTable> component.
So, first, let's refactor your deleteStudent() function:
export async function deleteStudent(id) {
const response = await fetch(`/students/${id}`, {
method: "DELETE",
});
return response.json();
}
You don't need to send any data with a DELETE request, you just need to hit the correct URL based on the id, which we can pass in to the method and dynamically include in the fetch() call.
Now, you need to find some way to pass that id into the deleteStudent() function. From what I can see, you are pulling in the student data here (I've paraphrased this):
const getEntries = async () => {
// students are pulled in, I'm assuming they have an 'id' property that corresponds to the 'id' that MongoDB has them stored under
const logEntries = await logEntry();
// and now data references the students
setdata(logEntries.students);
};
It looks like then you filter the students here:
const nameFilter = data.filter(list => {
return list.name.toLowerCase().includes(searchItem.item.toLowerCase());
});
And then render the filtered students with a call to .map(). This is where you can pass the id along in the onClick handler, assuming that you DO have an id field on these list elements. If you don't, then you will need to find a way to add the id in to this data:
nameFilter.map(list => {
return (
<tr>
<td>{list.name}</td>
<td>{list.city}</td>
<td>{list.address}</td>
<td>{list.phone}</td>
<td>{list.email}</td>
<td>
<a
className="waves-effect red btn-small"
onClick={() => deleteData(list.id)} // this is where the id should get passed on to the handler, and then dynamically included in the DELETE /students/:id url
>
Delete
</a>
</td>
</tr>
);
})
Then, in your deleteData() function, you will receive the id as a param, and you can call your deleteStudent(id) function to make the request to the backend:
const deleteData = async id => {
await deleteStudent(id);
};
There are some other things that need work, but you have the general idea correct! I'll give some hints towards further improvements below.
Do these need to be separate, or can they be combined?
import { logEntry } from "../Api/Api";
import { deleteStudent } from "../Api/Api";
Maybe clean up the DELETE route-handler:
app.delete("/students/:id", async (req, res, next) => {
const id = req.params.id;
try {
// generally, Mongoose Model's are represented with TitleCase
Student
.remove({ _id: id })
.exec() // is this needed? https://mongoosejs.com/docs/api/model.html#model_Model-remove
.then(data => {
res.json(data);
});
} catch (error) {
console.log(error);
}
});
There seems to be some extra state/hooks lying around in this Datatable:
function Datatable() {
// ... bunch of code
// do you need state for this?
const [removeStudent, setremoveStudent] = useState([]);
// ... more code
const getEntries = async () => {
// ...
setremoveStudent(deleteData); // not sure this is needed...
};