How to render fetched data from API - javascript

I'm trying to fetch data from an API that I want to render in a table. I am following this example, and have also tried others as well:
https://blog.hellojs.org/fetching-api-data-with-react-js-460fe8bbf8f2
When I try to console.log the state I get state is undefined. When I console.log the data I receive the correct data. I know how to solve my problem with pure JavaScript, but really want to make it work this way.
import React from "react";
import Row from '../components/Row';
class Table extends React.Component {
constructor() {
super();
this.state = {
users: [],
};
this.createNewUser = this.createNewUser.bind(this);
this.deleteExistingUser = this.deleteExistingUser.bind(this);
}
componentDidMount() {
console.log("Component did mount!");
fetch("http://localhost:8080/users")
.then(response => {
return response.json();
}).then(data => {
let users = data.response.map((row) => {
return (
<tr>
<td>{row.name}</td>
<td>{row.email}</td>
<td>{row.phone}</td>
<td>{row.age}</td>
<td>
<button className="red waves-effect waves-light btn">
Delete
</button>
</td>
</tr>
);
});
this.setState({users: users});
console.log("state", this.state.users);
});
}
render() {
return (
<table id="" className="highlight centered">
<thead>
<tr>
<th>Name</th>
<th>Email</th>
<th>Phone</th>
<th>Age</th>
<th>Delete</th>
</tr>
</thead>
<tbody id="table_body">
{this.state.users}
</tbody>
</table>
);
}
}
export default Table;

Okey, so after a little tinkering i was able to solve it.
I changed from:
let users = data.response.map((row) => {
return (
<tr>
<td>{row.name}</td>
<td>{row.email}</td>
<td>{row.phone}</td>
<td>{row.age}</td>
<td>
<button className="red waves-effect waves-light btn">
Delete
</button>
</td>
</tr>
);
});
to:
let users = data.map((row) => {
return <Row key={row.email} name={row.name} email={row.email}
phone={row.phone} age={row.age}/>
});

Related

How to add up two numbers gotten from firebase with react

Am new to React, and it feels like its very difficult to carry out mathematical calculations with react, Have been trying to add up two values gotten from firebase database but it keeps displaying the values as string and not adding the two values, Please I need help.
{contactObjects[id].gcc} + {contactObjects[id].lcc}
adding this two will only display all as string
E.g
if {contactObjects[id].gcc} is = 10 in firebase datebase and {contactObjects[id].lcc} as = 30
And adding + to the code wont sum up the two values, it will only display them as
10 + 30 which is in string and not 40
Please how can i go about it.
import React, { useState, useEffect } from "react";
import ContactForm from "./ContactForm";
import firebaseDb from "../firebase";
const Contacts = () => {
var [contactObjects, setContactObjects] = useState({});
var [currentId, setCurrentId] = useState("");
useEffect(() => {
firebaseDb.child("contacts").on("value", (snapshot) => {
if (snapshot.val() != null)
setContactObjects({
...snapshot.val(),
});
else setContactObjects({});
});
}, []); // similar to componentDidMount
const addOrEdit = (obj) => {
if (currentId == "")
firebaseDb.child("contacts").push(obj, (err) => {
if (err) console.log(err);
else setCurrentId("");
});
else
firebaseDb.child(`contacts/${currentId}`).set(obj, (err) => {
if (err) console.log(err);
else setCurrentId("");
});
};
const onDelete = (key) => {
if (window.confirm("Are you sure to delete this record?")) {
debugger;
firebaseDb.child(`contacts/${key}`).remove((err) => {
if (err) console.log(err);
else setCurrentId("");
});
}
};
return (
<>
<div className="jumbotron jumbotron-fluid">
<div className="container">
<h1 className="display-4 text-center">Contact Register</h1>
</div>
</div>
<div className="row">
<div className="col-md-5">
<ContactForm {...{ addOrEdit, currentId, contactObjects }} />
</div>
<div className="col-md-7">
<table className="table table-borderless table-stripped">
<thead className="thead-light">
<tr>
<th>Full Name</th>
<th>Mobile</th>
<th>Email</th>
<th>Address</th>
<th>Street</th>
<th>Address</th>
<th>Gcc</th>
<th>Lcc</th>
</tr>
</thead>
<tbody>
{Object.keys(contactObjects).map((id) => {
return (
<tr key={id}>
<td>{contactObjects[id].fullName}</td>
<td>{contactObjects[id].mobile}</td>
<td>{contactObjects[id].email}</td>
<td>{contactObjects[id].address}</td>
<td>{contactObjects[id].street}</td>
<td>{contactObjects[id].gcc}</td>
<td>{contactObjects[id].lcc}</td>
<td>
{contactObjects[id].gcc} +
{contactObjects[id].lcc}
</td>
<td>
<a
className="btn text-primary"
onClick={() => {
setCurrentId(id);
}}
>
<i className="fas fa-pencil-alt"></i>
</a>
<a
className="btn text-danger"
onClick={() => {
onDelete(id);
}}
>
<i className="far fa-trash-alt"></i>
</a>
</td>
</tr>
);
})}
</tbody>
</table>
</div>
</div>
</>
);
};
export default Contacts;
If I understand correctly, then just parse these values to int. If in DB these are 'string'
{parseInt(contactObjects[id].gcc) + parseInt(contactObjects[id].lcc)}

How to make open url on click on button in reactjs

In my code I am trying to do when I select row and click on button then this url open http://codeskulptor-assets.commondatastorage.googleapis.com/assets_clock_minute_arrow.png.
But right now in my code when I select row and click on button then url is not open.
How can we do that to open this url when I select row and click button the open url http://codeskulptor-assets.commondatastorage.googleapis.com/assets_clock_minute_arrow.png.
My code here https://codesandbox.io/embed/react-example-forked-o8tu5?codemirror=1
Anyone plz suggest any idea and help me out. I m stuck on that.
import React from 'react';
import axios from 'axios';
class ProvFileRptSearchResult extends React.Component {
constructor(props) {
super();
this.state = {
pymtDetails:[],
data: [],
rowDetails:[],
checkbox: false
};
// this.handleFile=this.handleFile.bind(this);
this.handleClick=this.handleClick.bind(this);
}
handleClick() {
const apiUrl = "http://localhost:9090/PrvFileRpt/getPrvFileData";
if (this.state.checkbox) {
fetch(apiUrl)
.then((response) => response.json())
.then((data) => {
this.setState({ data: data });
console.log("This is your data", data);
window.open("https://example.com", "_blank");
})
} else {
alert("Data not fetched!");
}
// console.log('click');
}
// handleClick(e) {
// e.preventDefault();
// console.log("The link was clicked");
// }
// handleFile()
// {
// //fetch birt report from here
// console.log("inside file ",this.state.rowDetails);
// }
rowSelected(j) {
// e.preventDefault();
console.log(j)
const rownum=j;
console.log("rownum=",rownum)
console.log(this.props.customerDetails[rownum] )
this.setState({rowDetails:this.props.customerDetails[rownum]}, () => {
});
}
render()
{
return(
<div>
<div className="table-employee" style={{ marginTop:"20px",border:" 1.5px solid darkgray" }}>
<table className="table table-hover table-bordered table-sm">
<thead>
<tr >
<th scope="col">Select</th>
<th scope="col"> LOAD DATE</th>
<th scope="col"> FILE DATE</th>
<th scope="col"> SERVICE</th>
<th scope="col"> PROVISIONER CODE </th>
<th scope="col"> DESCRIPTION</th>
</tr>
</thead>
<tbody>
{
this.props.customerDetails.map((type,j)=>{
return(
<tr>
<td ><input type="radio" preventDefault name="select" key={j} onClick={(e) =>this.rowSelected(j)} value={this.state.checkbox}
onChange={(e) =>
this.setState({ checkbox: !this.state.checkbox })
}/></td>
<td> {type.provis_file_stamp}</td>
<td> {type.provis_file_hdrdt}</td>
<td> {type.service_code}</td>
<td>{type.provisioner_code}</td>
<td>{type.provisioner_desc}</td>
</tr>
)
})
}
</tbody>
</table>
</div>
<div className="btn-submit" >
<button className="btn btn-primary" style={{marginRight:"30px"}} type="submit" onClick={this.handleClick}>FILE</button>
</div>
</div>
)
}
}
export default ProvFileRptSearchResult;
Call the openInNewTab with the URL. It will open the URL in a new browser tab. Remove '_blank', if you want to open it in the same tab.
const openInNewTab = (url) => {
const newWindow = window.open(url, '_blank', 'noopener,noreferrer')
if (newWindow) newWindow.opener = null
}
Well, if I understand correctly, you're trying to open a URL on button click?
If that's right, using window.open('https://example.com', '_blank') in your click handler will allow you to open any URL in a new tab.
First you need to find correct object using find method and then you can open url with window.open
Try following code:-
handleClick = () => {
const apiUrl = "https://mocki.io/v1/b512f8b8-64ab-46e4-9e0c-9db538a0ad9e";
if (this.state.checkbox) {
fetch(apiUrl)
.then((response) => response.json())
.then((data) => {
this.setState({ data: data });
const urlData = data.find(element => element.id === 3); // filter data with id
window.open(urlData.url, '_blank'); // open url here
});
} else {
alert("check the radio!");
}
};

React : Add backend filter to fetched data

I have the following component where I fetch data from a table, display them and have the ability to perform a search.
I want to add an additional filter to the fetched element. The filter is already coded and working in Laravel as following :
public function search(Request $request){
$search = $request ->get('q');
$Patient = Patient::where('name','Like','%'.$search.'%');
if ($request->has('gender')) {
$Patient->where('gender', $request->gender);
}
return $Patient->get();
}
As you can see in the controller you can perform a search and a filtering. So an example of directly accessing it will be :
http://localhost:8000/api/patients/search?q=John&gender=male
For now I'm able to display data and search it in react, but I have no idea on how to add additional filters to the link to fetch from. How to do so ?
Component :
class Patient extends React.Component {
constructor(props) {
super(props)
this.state = {
patients : [],
};
this.handleSearchChange = this.handleSearchChange.bind(this);
}
handleSearchChange(key){
console.log(key);
fetch('http://localhost:8000/api/patients/search?q='+key)
.then(response => response.json())
.then(response => {
this.setState({
patients: response})
console.log(response);
})
.catch(err => console.log(err));
}
componentDidMount() {
axios.get('api/patients')
.then(response => {
this.setState({
patients: response.data})
})
.catch(err => console.log(err));
}
render() {
return (
<div>
<Container>
<div>
<input
type="text"
className="form-control"
placeholder="Search..."
onChange={e => this.handleSearchChange(e.target.value)}
/>
<div class="dropdown">
<button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Dropdown button
</button>
<div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
<a class="dropdown-item" href="#">Male</a>
<a class="dropdown-item" href="#">Female</a>
</div>
</div>
</div>
<Table>
<Thead>
<Tr>
<Th>ID</Th>
<Th>FIRST NAME</Th>
<Th>LAST NAME</Th>
</Tr>
</Thead>
<Tbody>
{this.state.patients.reverse().map((patient) => (
<Tr>
<Td>
{patient.id}
</Td>
<Td>
{patient.firstname}
</Td>
<Td>
{patient.lastname}
</Td>
</Tr>
))}
</Tbody>
</Table>
</Container>
</div>
);
}
}
export default Patient;
You are quite close to it.
Your current implementation generates the search url as soon as the <input> field changes. If you want some other filters, you will need to store those filters values in a state before actually generating the url and fetching the data.
Here is how the gist would look like.
class Patient extends React.Component {
constructor(props) {
super(props)
this.state = {
patients : [],
filters: {q: '', gender: ''} // we add the filter property to the state
};
this.updateFilter = this.updateFilter.bind(this);
}
// this will fetch the new patients as soon as one of the filter has been updated
fetchPatients() {
const searchParams = new URLSearchParams();
const {q, gender} = this.state.filters
if (q) {
searchParams.set('q', q);
}
if (gender) {
searchParams.set('gender', gender);
}
const url = `http://localhost:8000/api/patients/search?${searchParams.toString()}`;
fetch(url)
.then(response => response.json())
.then(response => this.setState({patients: response}))
.catch(err => console.log(err));
}
// this will update a single filter
updateFilter(filter, value) {
const currentFilters = this.state.filters;
this.setState({filters: {...currentFilters, [filter]: value}});
this.fetchPatients()
}
render() {
return (
/*...*/
<input type="text" onChange={ev => this.updateFilter('q', ev.target.value)} />
/*...*/
<input type="text" onChange={ev => this.updateFilter('gender', ev.target.value)} />
);
}
}
check this example from pingcrm (build with laravel, inertiajs and vue), specifically when use lodash/pickBy conversion to replace a request URL
form: {
handler: throttle(function() {
let query = pickBy(this.form)
this.$inertia.replace(this.route('contacts', Object.keys(query).length ? query : { remember: 'forget' }))
}, 150),
deep: true,
},
Hope help.

Adding data fetched from an API into a Table automatically

I am fetching data from an API using Axios. I have a listRequest() method that is a GET request to the API, the addRow() method is used to add rows to the table automatically.
I want to be able to add the rows automatically with the fetched data.
Here is my code:
import React from 'react';
import axios from "axios";
class ShipmentsTable extends React.Component{
constructor(props){
super(props);
this.state = {
shipment: {
requestType: "Request Type",
customerName: "",
email: "",
companyName: "",
}
};
this.listRequest = this.listRequest.bind();
}
listRequest = () =>{
axios.get("http://localhost:8000/app/list/")
.then((response) =>{
let result = response.data;
console.log(result);
this.setState({shipment: result.data});
}).catch((error) =>{
console.log(error);
});
}
componentDidMount(){
this.listRequest();
}
addRow = () =>{
//destructuring
const {requestType, customerName, email, companyName} = this.state.shipment;
return this.state.shipment.map((shipment, index) =>{
<tr>
<td>{requestType}</td>
<td>{customerName}</td>
<td>{email}</td>
<td>{companyName}</td>
</tr>
});
}
render(){
return(
<table className="submittedShipmentsTable">
<thead>
<tr>
<td>
<th>Request Type</th>
</td>
<td>
<th>Customer Name</th>
</td>
<td>
<th>Email</th>
</td>
<td>
<th>Company Name</th>
</td>
</tr>
</thead>
<tbody>
{/*Adding Rows Automatically*/}
{this.addRow}
</tbody>
</table>
);
}
}
export default ShipmentsTable;
Question:
I want the data fetched from the API to be added to the table in the form of a row automatically
For map to work you need an array, ie:
this.state = {
shipments: [
{
requestType: "Request Type",
customerName: "",
email: "",
companyName: ""
}
]
};
Then you can do this in your render:
<tbody>
{this.state.shipments.map((shipment, index) => this.addRow(shipment))}
</tbody>
And add row will simply return the row:
addRow = ({ requestType, customerName, email, companyName }) => {
return (
<tr>
<td>{requestType}</td>
<td>{customerName}</td>
<td>{email}</td>
<td>{companyName}</td>
</tr>
);
};

How to display data in table using lodash in angular 9

I'm trying to display data in a table using lodash using angular 9 but when I'm pass data to a variable then it shows nothing.
Heare is my Code
Component.ts
list =[]
constructor(private apiservice: ApiServiceService) {}
ngOnInit(): void {
this.apiservice.filterData().then(resData => {
_.forEach(resData, boxes => {
_.forEach(boxes, data => {
_.forEach(data, val => {
if(val.name === 'GIP_asOfDate'){
_.forEach(val, asOfDate =>{
_.forEach(asOfDate, asd =>{
this.list = asd;
// console.log(this.list)
// console.log(asd.Name)
// console.log(asd.Count)
})
})
}
});
});
});
});
}
component.html
<table>
<thead>
<tr>
<th>As of Date</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let item of list">
<td>{{item.Name}}</td>
<td>{{item.Count}}</td>
</tr>
</tbody>
</table>

Categories