React Query: how to sort data - javascript

My main component
Here I'm fetching data from backend and receiving it well. Here how it looks like.
And now I want to sort them by their properties like step 1, step 2. I'm using React query to fetch data but I'm not sure how to sort it. Also, I already have sorting functions. But, I don't know how to change data based on the sorting atribute.
.
import React, { useEffect, useState } from "react";
import useFetchTable from "../../../../api/table/useFetchTable";
const TableList = () => {
const { data: response, status, isLoading } = useFetchTable();
// const [sortField, setSortField] = useState("");
// const [order, setOrder] = useState("asc");
// const handleSortingChange = (accessor) => {
// const sortOrder =
// accessor === sortField && order === "desc" ? "asc" : "desc";
// setSortField(accessor);
// setOrder(sortOrder);
// handleSorting(accessor, sortOrder);
// };
// const handleSorting = (sortField, sortOrder) => {
// if (sortField) {
// const sorted = [...data].sort((a, b) => {
// if (a[sortField] === null) return 1;
// if (b[sortField] === null) return -1;
// if (a[sortField] === null && b[sortField] === null) return 0;
// return (
// a[sortField].toString().localeCompare(b[sortField].toString(), "en", {
// numeric: true,
// }) * (sortOrder === "asc" ? 1 : -1)
// );
// });
// setData(sorted);
// }
// };
if (status === "error") {
return "Error";
}
if (isLoading) {
return "Loading...";
}
console.log(response);
const Print = ({ children }) => {
return (
<span className="text-xs bg-blue-100 rounded-full px-2 py-0.5 ml-2">
{children}%
</span>
);
};
return (
<div>
<table>
<thead className="border-b-2">
<tr>
<th className="py-1">Product Name</th>
<th>Purchases</th>
<th>US</th>
<th>Ch Step 1</th>
<th>Ch Step 2</th>
<th>CVR</th>
<th> 1</th>
<th>Upsell 2</th>
<th>Upsell 3</th>
</tr>
</thead>
<tbody>
{response.data?.map((row, idx) => (
<tr key={idx}>
<td>{row.name}</td>
<td>
{row.purchases[0]} <Print>{row.purchases[1]}</Print>
</td>
<td>
{row.unique_sessions} <Print>100</Print>
</td>
<td>
{row.checkout_step_1[0]} <Print>{row.checkout_step_1[1]}</Print>
</td>
<td>
{row.checkout_step_2[0]} <Print>{row.checkout_step_2[1]}</Print>
</td>
<td>
<Print>{`${row["cvr_%"]}`}</Print>
</td>
<td>
{row.upsell_1_takes[0]} <Print>{row.upsell_1_takes[1]}</Print>
</td>
<td>
{row.upsell_2_takes[0]} <Print>{row.upsell_2_takes[1]}</Print>
</td>
<td>
{row.upsell_3_takes[0]} <Print>{row.upsell_3_takes[1]}</Print>
</td>
</tr>
))}
</tbody>
</table>
TableList
{/* {data?.map((el) => {
el.title;
})} */}
</div>
);
};
export default TableList;

So for sorting based on your column header you can create a function to handle that onClick of the particular header. Like in the below code I have used the firstName column for sorting. On clicking the first name header it will trigger the function sortByFirstName and added the sort functionality in it and updated the state of the setTableData . Hope this helps.
import React, { useEffect, useState } from 'react'
import { useQuery } from 'react-query'
import './style.css'
function Example () {
const [sorted, setSorted] = useState({ sorted: "fname", reversed: false });
const [tableData, setTableData] = useState([])
const { data } = useQuery({
queryKey: ['repoData'],
queryFn: () =>
fetch('https://dummyjson.com/users?limit=10').then(
(res) => res.json(),
),
})
useEffect(() => {
if (data) {
setTableData(data?.users)
}
}, [data])
const sortByFirstName = () => {
setSorted({ sorted: "fname", reversed: !sorted.reversed })
const tableDataCopy = [...tableData];
tableDataCopy.sort((a, b) => {
let fnameA = a.firstName.toLowerCase();
let fnameB = b.firstName.toLowerCase();
if (sorted.reversed) {
return fnameB.localeCompare(fnameA)
}
return fnameA.localeCompare(fnameB)
})
setTableData(tableDataCopy)
}
return (
<div className='h-full w-full'>
<table className='data' cellspacing="0" cellpadding="0">
<thead>
<tr>
<th onClick={ sortByFirstName }>First Name</th>
<th >Last Name</th>
<th >Gender</th>
<th >Email</th>
<th >Bloodgroup</th>
<th >Age</th>
<th > Weight</th>
<th >Maiden Name</th>
<th >Phone</th>
</tr>
</thead>
<tbody>
{ tableData?.map((row, idx) => (
<tr key={ idx }>
<td>{ row.firstName }</td>
<td>
{ row.lastName }
</td>
<td>
{ row.gender }
</td>
<td>
{ row.email }
</td>
<td>
{ row.bloodGroup }
</td>
<td>
{ row.age }
</td>
<td>
{ row.weight }
</td>
<td>
{ row.maidenName }
</td>
<td>
{ row.phone }
</td>
</tr>
)) }
</tbody>
</table>
</div>
)
}
export default Example

Related

listing joined query with react

I want to list my code. I listed single query BUT the query i want to list is joined query.
app.get('/dormitory1', (req, res)=>{
client.query(`Select * from dormitory1`, (err, result)=>{
if(!err){
res.send(result.rows);
}
});
})
this is my get request, database code
import React, { useEffect, useState } from 'react'
import UpdateDormitory from './UpdateDormitory';
const ListDormitory = () => {
const[dormitory1,setDormitory1]=useState([])
const deletedormitory = async id => {
try {
const deletedormitory = await fetch(`http://localhost:2103/dormitory1/${id}`, {
method: "DELETE"
});
setDormitory1(dormitory1.filter(dormitory1=> dormitory1.dormitoryid!== id));
} catch (err) {
console.error(err.message);
}
};
const getDormitory = async () => {
try {
const response = await fetch("http://localhost:2103/dormitory1");
const jsonData = await response.json();
setDormitory1(jsonData);
} catch (err) {
console.error(err.message);
}
};
useEffect(() => {
getDormitory();
}, []);
console.log(dormitory1);
return (
<>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#4.4.1/dist/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous"></link>
{" "}
<table class="table mt-5 text-center">
<thead>
<tr>
<th>Name of Dormitory</th>
<th>Location</th>
<th>Type of Dormitory</th>
<th>Capacity</th>
<th>Current Capacity</th>
<th>Check In Time </th>
<th>Check Out Time</th>
<th>Number Of Meals</th>
<th>Phone Number</th>
<th>Edit</th>
<th>Delete</th>
</tr>
</thead>
<tbody>
{dormitory1.map(dormitory1 => (
<tr key={dormitory1.dormitoryid}>
<td>{dormitory1.nameofdormitory}</td>
<td>{dormitory1.locationid}</td>
<td>{dormitory1.typeofdormitory}</td>
<td>{dormitory1.capacity}</td>
<td>{dormitory1.currentcapacity}</td>
<td>{dormitory1.checkintime}</td>
<td>{dormitory1.checkouttime}</td>
<td>{dormitory1.numberofmeals}</td>
<td>{dormitory1.phone}</td>
<td>
<UpdateDormitory dormitory1={dormitory1} />
</td>
<td>
<button
className="btn btn-danger"
onClick={() => deletedormitory(dormitory1.dormitoryid)}
>
Delete
</button>
</td>
</tr>
))}
</tbody>
</table>
</>
)
}
export default ListDormitory
and this my listing code
they're working
they're picture:enter image description here
app.get("/search", async (req, res) => {
try {
const { city,district,typeofdormitory} = req.query;
const search = await client.query(
`SELECT (dormitory1.nameofdormitory,
location.city,
location.district,
dormitory1.typeofdormitory,
dormitory1.capacity,
dormitory1.checkintime,
dormitory1.checkouttime,
dormitory1.numberofmeals,
dormitory1.phone
) FROM location
inner join dormitory1 on location.locationid=dormitory1.locationid
WHERE (city ILIKE $1 and district ILIKE $2 and typeofdormitory ILIKE $3)`,
[`%${city}%`,`%${district}%`,`%${typeofdormitory}%`]
);
res.json(search.rows);
} catch (err) {
console.error(err.message);
}
});
the query I want to list
import React, { useEffect, useState } from 'react'
const Search = () => {
const[search,setSearch]=useState([]);
const[dormitory1,setDormitory1]=useState([]);
const[location,setLocation]=useState([]);
const getSearch = async () => {
try {
const response = await fetch("http://localhost:6302/search");
const jsonData = await response.json();
setSearch(jsonData);
} catch (err) {
console.error(err.message);
}
};
useEffect(() => {
getSearch();
}, []);
console.log(search);
return (
<>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#4.4.1/dist/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous"></link>
{" "}
<table class="table mt-5 text-center">
<thead>
<tr>
<th>City</th>
<th>District</th>
<th>Name of Dormitory</th>
<th>Type of Dormitory</th>
<th>Capacity</th>
<th>Current Capacity</th>
<th>Check In Time </th>
<th>Check Out Time</th>
<th>Number Of Meals</th>
<th>Phone Number</th>
</tr>
</thead>
<tbody>
{search.map(search => (
<tr key={search.locationid}>
<td>{search.city}</td>
<td>{search.district}</td>
</tr>
))}
{/* {search.map(dormitory1 => (
<tr key={dormitory1.dormitoryid}>
<td>{dormitory1.nameofdormitory}</td>
<td>{dormitory1.typeofdormitory}</td>
<td>{dormitory1.capacity}</td>
<td>{dormitory1.checkintime}</td>
<td>{dormitory1.checkouttime}</td>
<td>{dormitory1.numberofmeals}</td>
<td>{dormitory1.phone}</td>
</tr>
))} */}
</tbody>
</table>
</>
)
}
export default Search
I wrote this code but it doesn't work
they're picture:enter image description here

How to group by two columns? ReactJS

The code that I posted below is the API request from which I make a table. This table has 4 columns: id, userid, title. I want to understand how I can sort by userid and title, as shown in the photo. It would be great if the steps were described in detail.
I'm trying to group the tab as shown in the photo, but I can't.
Can you suggest/show me how to do this?
Also wanted to know how to reset the group value of a column?
I will be grateful for any help.
My code:
import React from "react";
import "./GroupByUserID.css";
import { Link } from "react-router-dom";
export default class GroupByUserID extends React.Component {
// Constructor
constructor(props) {
super(props);
this.state = {
items: [],
};
}
componentDidMount = () => {
this.apiFetch();
};
//Fetch data from API
apiFetch = () => {
return fetch("https://jsonplaceholder.typicode.com/todos")
.then((res) => res.json())
.then((json) => {
this.setState((prevState) => {
return { ...prevState, items: json };
});
});
};
// Sort UserID
setSortedItemsUserID = () => {
const { items } = this.state;
const sortedUserID = items.sort((a, b) => {
if (a.userId < b.userId) {
return items.direction === "ascending" ? -1 : 1;
}
if (a.userId > b.userId) {
return items.direction === "ascending" ? 1 : -1;
}
return 0;
});
console.log(sortedUserID);
this.setState((prevState) => {
return { ...prevState, items: sortedUserID };
});
};
render() {
const { items } = this.state;
return (
<div>
<h1>Home Page</h1>
<table>
<thead>
<tr>
<th>
<Link target="self" to="/">
View Normal
</Link>
</th>
<th>Group By UserID</th>
</tr>
</thead>
<thead>
<tr>
<th>
User ID
<button
type="button"
onClick={() => this.setSortedItemsUserID()}
>
⬇️
</button>
</th>
<th>Title</th>
</tr>
</thead>
<tbody>
{items.map((item) => (
<tr key={item.userId + item.title}>
<td>{item.userId}</td>
<td>{item.title}</td>
</tr>
))}
</tbody>
</table>
</div>
);
}
}

tried a lot but not able to make deletehandler function working. here is my code

This is my librarylist component in which i pass deletehandler function to delete the row from library management. I don't know which part of the code is causing the problem. Any helps/suggestions are welcome.
LibraryBookList.js
const LibraryBookList = (props) => {
const[database, setDatabase]=useState()
const deleteHandler = (bookdataId) => {
const newDatabase=[...database];
const index= database.findIndex((bookdata)=>bookdata.id===bookdataId)
newDatabase.splice(index,1)
setDatabase(newDatabase);
} ;
return (
<ul className={classes.list}>
{props.database.map((bookdata) =>
(<LibraryBook
key={bookdata.key}
id={bookdata.id}
bookname={bookdata.bookName}
author={bookdata.author}
publisher={bookdata.publisher}
pages={bookdata.pages}
serialno={bookdata.serialNo}
onSelect={deleteHandler}
/>
))}
</ul>
)};
here i pass deletehandler via props
LibraryBook.js
const LibraryBook = (props) => {
return (
<li>
<table className={classes.table}>
<tbody>
<tr className={classes.table_row}>
<td className={classes.row_data}>{props.serialno}</td>
<td className={classes.row_data}>{props.pages}</td>
<td className={classes.row_data}>{props.bookname}</td>
<td className={classes.row_data}>{props.author}</td>
<td className={classes.row_data}>{props.publisher}</td>
<td>
<button className={classes.delete_btn} onClick={(props.onSelect(props.id))}>
Delete
</button>
</td>
</tr>
</tbody>
</table>
</li>
export default LibraryBookList;
**BookData.js **
const BookData = (props) => {
const [isLoading, setIsLoading] = useState(true);
const [loadedLibrarydata, setLoadedLibrarydata] = useState();
useEffect(() => {
setIsLoading(true);
fetch(
"https://librarymanagement-70ab2-default-rtdb.firebaseio.com/database.json"
)
.then((response) => {
// console.log('response',response.json())
return response.json();
})
.then((data) => {
const database = [];
console.log("data", data);
for (const key in data) {
const bookdata = {
id: key,
...data[key],
};
database.push(bookdata);
}
setIsLoading(false);
setLoadedLibrarydata(database);
});
}, []);
if (isLoading) {
return (
<section>
<p>Loading.....</p>
</section>
);
}
return (
<section>
<h1>Book Data Base</h1>
<table className={classes.table}>
<thead>
<tr className={classes.table_row}>
<th className={classes.row_heading}>Serial No</th>
<th className={classes.row_heading}>Pages</th>
<th className={classes.row_heading}>Book Name</th>
<th className={classes.row_heading}>Author</th>
<th className={classes.row_heading}>Publisher</th>
</tr>
</thead>
</table>
{loadedLibrarydata && loadedLibrarydata.length && (
<LibraryBooklist database={loadedLibrarydata} />
)}
</section>
);
};
export default BookData;
NewDataBase.js
const NewDataBase = () => {
const history=useHistory();
const addDataHandler = (bookData) => {
console.log('bookData',bookData);
fetch(
"https://librarymanagement-70ab2-default-rtdb.firebaseio.com/database.json",
{
method: "POST",
body: JSON.stringify(bookData),
headers: {
"Content-type": "application/json",
},
}
).then(()=>{
history.replace('/')
})
};
return (
<section>
<DataBaseForm onAddNewData={addDataHandler} />
</section>
);
};
export default NewDataBase;
The code has a few issues: 1) props.onSelect(props.id) inside onClick. Instead you should give a referance to that function. 2) You didn't have anything in database state before you click delete button. That is why ... spread operator didn't work 3) You are displaying props.database instead of database state. That is way the changes didn't show up even after you deleted a bookdata. I also fixed some small issues. Now it is working perfectly:
// !! you can put all the code into one file and run for testing.
// !! I removed stylings as I didn't have the source
import {useState, useEffect} from 'react'
const LibraryBooklist = (props) => {
const[database, setDatabase]=useState(props.database)
const deleteHandler = (bookdataId) => {
const newDatabase=database.filter((bookdata)=>bookdata.id!==bookdataId);
setDatabase(newDatabase);
}
return (
<ul>
{database.map((bookdata) =>
<LibraryBook
key={bookdata.id}
id={bookdata.id}
bookname={bookdata.bookName}
author={bookdata.author}
publisher={bookdata.publisher}
pages={bookdata.pages}
serialno={bookdata.serialNo}
onSelect={deleteHandler}
/>
)}
</ul>
)};
const LibraryBook = (props) => {
const {id, onSelect} = props
return (
<li>
<table>
<tbody>
<tr>
<td>{props.serialno}</td>
<td>{props.pages}</td>
<td>{props.bookname}</td>
<td>{props.author}</td>
<td>{props.publisher}</td>
<td>
<button onClick={() => onSelect(id)}>
Delete
</button>
</td>
</tr>
</tbody>
</table>
</li>
)}
const BookData = (props) => {
const [isLoading, setIsLoading] = useState(true);
const [loadedLibrarydata, setLoadedLibrarydata] = useState();
useEffect(() => {
setIsLoading(true);
fetch(
"https://librarymanagement-70ab2-default-rtdb.firebaseio.com/database.json"
)
.then((response) => {
// console.log('response',response.json())
return response.json();
})
.then((data) => {
const database = [];
for (const key in data) {
const bookdata = {
id: key,
...data[key],
};
database.push(bookdata);
}
setIsLoading(false);
setLoadedLibrarydata(database);
});
}, []);
if (isLoading) {
return (
<section>
<p>Loading.....</p>
</section>
);
}
return (
<section>
<h1>Book Data Base</h1>
<table>
<thead>
<tr>
<th>Serial No</th>
<th>Pages</th>
<th>Book Name</th>
<th>Author</th>
<th>Publisher</th>
</tr>
</thead>
</table>
{loadedLibrarydata && loadedLibrarydata.length && (
<LibraryBooklist database={loadedLibrarydata} />
)}
</section>
);
};
export default BookData;

Fetching data and conditional rendering with React useEffect

I'm building a MERN stack app that fetches data about college classes and render it in a table. The CoursesTable.js component looks like this:
import React, { useState, useEffect } from 'react';
import { Table } from 'react-materialize';
import axios from 'axios';
const CoursesTable = () => {
const [courses, setCourses] = useState([]);
useEffect(() => {
const fetchData = async () => {
const coursesData = await axios.get('http://localhost:8001/')
setCourses(coursesData.data)
}
fetchData()
}, [])
return (
<Table>
<thead>
<tr>
<th data-field="course-name">
Name
</th>
<th data-field="course-prof">
Prof.
</th>
<th data-field="course-code">
Code
</th>
</tr>
</thead>
<tbody>
{
courses.length >= 1
? courses.map(course =>
<tr key={course._id}>
<td>
{course.name}
</td>
<td>
{course.prof}
</td>
<td>
{course.code}
</td>
</tr>
)
: <tr>
<td>There is no course</td>
</tr>
}
</tbody>
</Table>
);
}
export default CoursesTable;
I use conditional rendering so that if courses is empty, a message that goes like There is no course is displayed. When the array is full, the data is rendered in table rows.
My issue is: when courses is full and CoursesTable.js is rendered, the There is no course message always comes up for just a few milliseconds before being replaced with the data.
How can I fix this? Thanks for your help guys!
You could have a conditional check in place, e.g.:
import React, { useState, useEffect } from 'react';
import { Table } from 'react-materialize';
import axios from 'axios';
const CoursesTable = () => {
const [courses, setCourses] = useState([]);
const [isLoading, setLoading] = useState(true);
useEffect(() => {
const fetchData = async () => {
const coursesData = await axios.get('http://localhost:8001/')
setCourses(coursesData.data)
setLoading(false);
}
fetchData()
}, [])
if(isLoading) { return <div> Loading ... </div> };
return (
<Table>
<thead>
<tr>
<th data-field="course-name">
Name
</th>
<th data-field="course-prof">
Prof.
</th>
<th data-field="course-code">
Code
</th>
</tr>
</thead>
<tbody>
{
courses.length >= 1
? courses.map(course =>
<tr key={course._id}>
<td>
{course.name}
</td>
<td>
{course.prof}
</td>
<td>
{course.code}
</td>
</tr>
)
: <tr>
<td>There is no course</td>
</tr>
}
</tbody>
</Table>
);
}
export default CoursesTable;

How to display data with id React Js and Firebase

I'm working on a project, and I would like to display some data from my firebase database,
I can show some of them, but I want to display the rest of the data of my "listClients" on a box, linked to the checkbox with the id.
listClients.js it's where i map the data from the db
import React, { Component } from "react";
import * as firebase from "firebase";
import { Table, InputGroup } from "react-bootstrap";
class ListClients extends React.Component {
state = {
loading: true
};
componentWillMount() {
const ref = firebase.database().ref("listClients");
ref.on("value", snapshot => {
this.setState({ listClients: snapshot.val(), loading: false });
});
}
render() {
if (this.state.loading) {
return <h1>Chargement...</h1>;
}
const clients = this.state.listClients.map((client, i) => (
<tr key={i}>
<td>
<input id={client.id} type="checkbox" onChange={this.cbChange} />
</td>
<td>{client.nom}</td>
<td>{client.prenom}</td>
</tr>
));
const clientsAdresses = this.state.listClients.map((clientAdresse, i) => (
<tr key={i}>
<td id={clientAdresse.id}>{clientAdresse.adresse}</td>
</tr>
));
return (
<>
<Table className="ContentDesign" striped bordered hover>
<thead>
<tr>
<th></th>
<th>First Name</th>
<th>Last Name</th>
</tr>
</thead>
<tbody>{clients}</tbody>
</Table>
<Table className="ContentDesign" striped bordered hover>
<thead>
<tr>
<th>Adresse : </th>
</tr>
</thead>
<tbody>{clientsAdresses}</tbody>
</Table>
</>
);
}
}
export default ListClients;
my data :
I only want the "adresse" of the id where the checkbox is check
Thank you
ERROR :
To retrieve the adresse from the database then use the following code:
componentWillMount() {
const ref = firebase.database().ref("listClients");
ref.on("value", snapshot => {
snapshot.forEach((subSnap) => {
let address = subSnap.val().adresse;
});
});
}
First add a reference to node listClients the using forEach you can iterate and retrieve the adresse
If you want to get the adresse according to the id, then you can use a query:
const ref = firebase.database().ref("listClients").orderByChild("id").equalTo(0);

Categories

Resources