Calling async method in React functional component - javascript

I have a question about a good way to solve this problem I have in React. I need to gather currencies from my own API that I've created, that works perfectly and I iterate it in my return statement of the React component. When iterating, I want to use the "item.pairs" data to use as an argument for a method call (async method) to get price information and render it. How can this be accomplished?
I added a method getCurrencyData, I tried calling that in the return statement inside the loop, but it will not work, and I have searched for this and it's not possible to do that in that way. So how can I do this?
The used code is below:
const Start = () => {
let match = useRouteMatch()
const [currencies, setCurrencies] = useState([])
const [currencyPrices, setCurrencyPrices] = useState([])
useEffect(() => {
getAllCurrencies()
}, [])
const getCurrencyData = async (ticker) => {
try {
const response = await KrakenService.getByTicker(ticker)
return Object.values(response.data.result)[0].c[0]
} catch (err) {
console.log(err)
}
}
const getAllCurrencies = async () => {
try {
const response = await CryptoCurrencyService.getAll()
setCurrencies(response.data.results)
} catch (err) {
console.log(err)
}
}
return(
<div className='Start'>
<Switch>
<Route path={`${match.path}/:currencyId`}>
test
</Route>
<Route path={match.path}>
<Container className="cc-container">
<Row>
<Table hover className="cc-table">
<thead>
<tr>
<th>#</th>
<th>Name</th>
<th>Price</th>
<th>24h %</th>
<th>7d %</th>
<th>Market Cap</th>
<th>Volume (24h)</th>
<th>Circulating Supply</th>
<th>Last 30 Days</th>
</tr>
</thead>
{currencies &&
currencies.map((item, index) =>
<tbody>
<tr>
<td>{index + 1}</td>
<td><Image src={item.logo} width="38" roundedCircle /> {item.name}</td>
<td>{item.pairs}</td> HERE I WANT TO FETCH DATA
</tr>
</tbody>
)
}
</Table>
</Row>
</Container>
</Route>
</Switch>
</div>
)
}
export default Start

Maybe create component for Price information?
// PriceInformation component
const PriceInformation = ({ ticker }) => {
const [priceInfo, setPriceInfo] = useState(null)
useEffect(() => {
getCurrencyData(ticker)
}, [])
const getCurrencyData = async (ticker) => {
try {
const response = await KrakenService.getByTicker(ticker)
setPriceInfo(Object.values(response.data.result)[0].c[0]);
// return Object.values(response.data.result)[0].c[0]
} catch (err) {
console.log(err)
}
}
return (
// your code for ui
)
}
// Start component
const Start = () => {
// code ...
return (
<div className='Start'>
<Switch>
<Route path={`${match.path}/:currencyId`}>
test
</Route>
<Route path={match.path}>
<Container className="cc-container">
<Row>
<Table hover className="cc-table">
<thead>
<tr>
<th>#</th>
<th>Name</th>
<th>Price</th>
<th>24h %</th>
<th>7d %</th>
<th>Market Cap</th>
<th>Volume (24h)</th>
<th>Circulating Supply</th>
<th>Last 30 Days</th>
</tr>
</thead>
{currencies &&
currencies.map((item, index) =>
<tbody>
<tr>
<td>{index + 1}</td>
<td><Image src={item.logo} width="38" roundedCircle /> {item.name}</td>
{ /* <td>{item.pairs}</td> HERE I WANT TO FETCH DATA */ }
<td><PriceInformation ticker={item.pairs}/></td>
</tr>
</tbody>
)
}
</Table>
</Row>
</Container>
</Route>
</Switch>
</div>
)
}

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

React mapping rendering issue

I'm having a very perplexing issue that I wonder if anyone could help with. I have objects being mapped as arrays into some html(/jsx). The objects aren't rendering. Strangely, though, in the debugger it does show each value being attributed to the insertions in the html -- but it's not rendering. any ideas?
The picture below is an example of one object in the reservations array showing as mapping in the debugger, whereas the rendering actually stays as the second picture.
The axios http request, in a promise with another request:
const getReservations =
axios
.get(`${api_url}/reservations`, {
headers: {
'Authorization': `Bearer ${sessionStorage.token}`
}
})
.then((res) => {
setReservations(reservations => ([...reservations, ...res.data]));
})
const getRoomTypes =
axios
.get(`${api_url}/room-types`, {
headers: {
'Access-Control-Allow-Origin': `${ui_url}`,
'Authorization': `Bearer ${sessionStorage.token}`
}
})
.then((res) => {
setRoomTypes(roomTypes => ([...roomTypes, ...res.data]));
})
Promise.all([getReservations, getRoomTypes])
.catch(() => {
setError(connectionError);
});
}, []);
Which passes the data to the rendered component:
return (
<div>
<h2>Reservations</h2>
<Link className="button" to="/reservations/create">Create</Link>
<br />
<br />
<ReservationDiv error={error} resData={reservations} />
</div>
);
The component in which the objects are rendered:
const ReservationDiv = (props) => {
const reservations = props.resData;
const renderTableData = () => {
reservations.map((reservation) => {
const { id, user, guestEmail, roomTypeId, checkInDate,
numberOfNights } = reservation;
return (
<tr key={id}>
<td className="res">{id}</td>
<td className="user">{user}</td>
<td className="email">{guestEmail}</td>
<td className="room">{roomTypeId}</td>
<td className="date">{checkInDate}</td>
<td className="nights">{numberOfNights}</td>
</tr>
);
});
}
return (
<table>
<tbody>
<tr>
<th>ID</th>
<th>Input by</th>
<th>Guest Email</th>
<th>Room Type</th>
<th>Check-in Date</th>
<th># of Nights</th>
<th>Total</th>
</tr>
{renderTableData()}
</tbody>
</table>
);
}
I can also provide quoted code, but I figured the problem seems to be something more fundamental, since it's a difference between a representation of a thing and the thing itself
You need to return the mapped array of JSX objects
const renderTableData = () => {
return reservations.map((reservation) => {
//...

Search in custom table - React

I'm trying to make a table with api data searchable. I'm on my way, but unsure on how to proceed further.
Code looks like this:
const [searchTerm, setSearchTerm] = useState("");
const [searchResults, setSearchResults] = useState([]);
const handleChange = event => {
setSearchTerm(event.target.value);
};
useEffect(() => {
const results = apiData.filter(person =>
person.toLowerCase().includes(searchTerm)
);
setSearchResults(results);
}, [searchTerm]);
const renderPerson = (contact, index) => {
return (
<tr key={index}>
<td>{contact.ID}</td>
<td>{contact.Info.Name}</td>
<td>{contact.InfoID}</td>
<td>{contact.Info.DefaultEmail.EmailAddress}</td>
<td>{contact.Info.DefaultPhone.Number}</td>
<td>{contact.Info.InvoiceAddress.AddressLine1}</td>
</tr>
)
}
return (
<Fragment>
<input type="text" value={searchTerm} onChange={handleChange} placeholder="Søk.."></input>
<table id="myTable">
<thead>
<tr className="header">
<th>ID</th>
<th>Navn</th>
<th>Info Id</th>
<th>E-post</th>
<th>Telefon</th>
<th>Adresse</th>
</tr>
</thead>
<tbody>
{apiData.map(renderPerson)}
</tbody>
</table>
</Fragment>
)
https://dev.to/asimdahall/simple-search-form-in-react-using-hooks-42pg
I've followed this guide, but since I have the renderPerson function, I'm a bit unsure on how to handle this.
Question: Is there any way to get this working, or am I approaching it the wrong way? I'm aware that I need to put searchResult in the tbody somehow, but then the table won't be populated.
Any help is much appreciated
Edit: displaying code for getting apiData:
useEffect(() => {
getContacts()
}, [])
const getContacts = () => {
$.ajax({
url: `http://localhost:5000/getContacts`,
type: "POST",
data: ajaxObj,
success: (data) => {
let response = JSON.parse(data)
setApiData(response)
setLoading(false)
},
error: () => {
console.log("noe feilet?");
}
});
}
console.log(apiData)
Data looks like this:
data
Change apiData to searchResults on render
<tbody>
{searchResults.map(renderPerson)}
</tbody>
Change your filter way result (Updated)
const results = apiData.filter(person =>
person.Info.Name.toLowerCase().includes(searchTerm)
);
....
const renderPerson = (item, index) => {
return (
<tr key={index}>
<td>{item.ID}</td>
<td>{item.Info.Name}</td>
<td>{item.InfoID}</td>
<td>{item.Info.DefaultEmail.EmailAddress}</td>
<td>{item.Info.DefaultPhone.Number}</td>
<td>{item.Info.InvoiceAddress.AddressLine1}</td>
</tr>
)
}
Try this
export default function () {
const [searchTerm, setSearchTerm] = useState("");
const [searchResults, setSearchResults] = useState([]);
const apiData=[
{
ID:'1222',
Info:{
ID:'1222',
EmailAddress:'test#test.com',
Number:'2222222222',
AddressLine1:'test'
}
},
{
ID:'2333',
Info:{
ID:'2333',
EmailAddress:'test2#test.com',
Number:'1111111111',
AddressLine1:'test2'
}
}
]
const handleChange = event => {
setSearchTerm(event.target.value);
if(event.target.value){
const results = apiData.filter(person =>
person.ID.toLowerCase().includes(event.target.value)
);
setSearchResults(results);
}else{
setSearchResults([]);
}
};
const renderPerson = (contact, index) => {
return (
<tr key={index}>
<td>{contact.ID}</td>
<td>{contact.Info.Name}</td>
<td>{contact.Info.ID}</td>
<td>{contact.Info.EmailAddress}</td>
<td>{contact.Info.Number}</td>
<td>{contact.Info.AddressLine1}</td>
</tr>
)
}
return (
<Fragment>
<input type="text" value={searchTerm} onChange={handleChange} placeholder="Søk.."></input>
<table id="myTable">
<thead>
<tr className="header">
<th>ID</th>
<th>Navn</th>
<th>Info Id</th>
<th>E-post</th>
<th>Telefon</th>
<th>Adresse</th>
</tr>
</thead>
<tbody>
{searchResults.map(renderPerson)}
</tbody>
</table>
</Fragment>
)
}

How can I sort column in child component clicking on heading in parent component?

The problem is I don't know how to put effect from parent component to child component...
I'm creating sorting function.
tableSort = (event, sortKey) => {
const {data} = this.state;
data.sort((a,b) => a[sortKey].localeCompare(b[sortKey]) )
this.setState({ data })
}
and then I'm trying to render that in my table
render() {
const {data} = this.state
return (
<>
<Table>
<Thead>
<Tr>
<Th onClick={e => this.tableSort(e, 'pool number')}>Pool Number</Th>
<Th>Sender</Th>
<Th>Not Routed Reason</Th>
<Th>Sent Date Time</Th>
<Th>Requested Delivery Report Mask Text</Th>
<Th>Delivery Report Received Date Time</Th>
<Th>isUnicode</Th>
<Th>MessageUUID</Th>
</Tr>
</Thead>
{this.renderData(data)}
</Table>
</>
)
}
The child component is called in this component and it locks like this..
import React from 'react'
import { Tbody, Tr, Td } from 'react-super-responsive-table'
const TablePageList = ({data}) => {
const {poolNumber, sender, notRoutedReason, sentDateTime, requestedDeliveryReportMaskText,
deliveryReportReceivedDateTime, isUnicode, messageUUID} = data
return (
<Tbody>
<Tr>
<Td>{poolNumber}</Td>
<Td>{sender}</Td>
<Td>{notRoutedReason}</Td>
<Td>{sentDateTime}</Td>
<Td>{requestedDeliveryReportMaskText}</Td>
<Td>{deliveryReportReceivedDateTime}</Td>
<Td>{isUnicode}</Td>
<Td>{messageUUID}</Td>
</Tr>
</Tbody>
)
}
export default TablePageList
So how can I access and sort my Td from Th?
You should call the child component from parent. You didn't call any child component.
Try below code.
import child compenent url.
import TablePageList from "./TablePageList";
And then keep state data.
this.state = {
data:[]
}
Also change function setState and order data.
tableSort = (event, sortKey) => {
const {data} = this.state;
data.sort((a,b) => a[sortKey].localeCompare(b[sortKey]) )
this.setState({ data: data })
}
And call TablePageList component below </Thead>
render() {
const { data } = this.state;
return (
<Table>
<Thead>
<Tr>
<Th onClick={e => this.tableSort(e, "pool number")}>
Pool Number
</Th>
<Th>Sender</Th>
<Th>Not Routed Reason</Th>
<Th>Sent Date Time</Th>
<Th>Requested Delivery Report Mask Text</Th>
<Th>Delivery Report Received Date Time</Th>
<Th>isUnicode</Th>
<Th>MessageUUID</Th>
</Tr>
</Thead>
{data.map(element => {
<TablePageList data={element}></TablePageList>;
})}
</Table>
);
}
And then you get data and fill it.
const TablePageList = ({ data }) => {
return (
<Tbody>
<Tr>
<Td>{data.poolNumber}</Td>
<Td>{data.sender}</Td>
<Td>{data.notRoutedReason}</Td>
<Td>{data.sentDateTime}</Td>
<Td>{data.requestedDeliveryReportMaskText}</Td>
<Td>{data.deliveryReportReceivedDateTime}</Td>
<Td>{data.isUnicode}</Td>
<Td>{data.messageUUID}</Td>
</Tr>
</Tbody>
);
};

Filter method on another method?

I want to run a filter method on the renderTable method that I've defined below. Is it possible to do:
renderTable().filter(x => x.name)?
Right now, I have a table with rows of each category and their results from a url that provided some json data.
I would like to make a feature that allows users to adjust the setting to return their desired results.
CODE
const renderTable = () => {
return players.map(player => {
return (
<tr>
<td>{player.name}</td>
<td>{player.age}</td>
<td>{player.gender}</td>
<td>{player.state}</td>
<td>{player.status}</td>
</tr>
)
})
}
return (
<div className = "App">
<h1>Players</h1>
<table id = "players">
<thead>
<tr>
<th>Name</th>
<th>Age</th>
<th>Gender</th>
<th>State</th>
<th>Status</th>
</tr>
</thead>
<tbody>{renderTable()}</tbody>
</table>
</div>
);
You can apply the filter before the map. Here, give this a try:
const renderTable = () => {
return players
.filter(player => player.state === "NSW")
.map(player => {
return (
<tr>
<td>{player.name}</td>
<td>{player.age}</td>
<td>{player.gender}</td>
<td>{player.state}</td>
<td>{player.status}</td>
</tr>
);
});
};
Here's a Working Sample CodeSandbox for your ref.
Yes you can. Just filter before map players.filters(...).map. But this is better
const renderTable = () => {
const rows = []
players.forEach((player, index) => {
if(player.name) {
rows.push(
<tr key={index}>
<td>{player.name}</td>
<td>{player.age}</td>
<td>{player.gender}</td>
<td>{player.state}</td>
<td>{player.status}</td>
</tr>
)
}
})
return rows;
}

Categories

Resources