I am able to save data into my database. However, i want to know how to show/render the fetch data on my screen after i run my fetch request.
When i add data i am able to push to render on my page. But what i want is, once i run my fetch data function, how do i render the response that i get onto my screen ?
My Json data after fetch looks like this when i console.log(json.data.shipping)
0: { name: "Samsung A10", phone: "001-2342-23429"}
1: {name: "Iphone Xs", phone: "001-12193-1219"}
PS: Beginner with React JS
Below is how i save data
state = {
shippings: userData,
addNewData: {
name: '',
phone: ''
},
};
addData() {
const { name,phone} = this.state.addNewData;
if (name!== '' && phone = "") {
let newData = {
...this.state.addNewData,
id: new Date().getTime()
}
let shippings = this.state.shippings;
fetch( 'http://facicla:5000/api', {
method:'post',
/* headers are important*/
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
body: JSON.stringify(this.state.addNewData)
})
.then(response => {
return response.json();
shippings.push(newData);
NotificationManager.success('Sucess!');
})
}
}
userData
export default [
{
name: 'Shipping-Car',
phone: '001-72342-2342',
} ]
Fetch Data
fetchAllData(){
return this.fetchPost().then(([response,json]) => {
if(response.status === 200)
{
console.log(json.data.shipping)
0: { name: "Samsung A10", phone: "001-2342-23429"}
1: {name: "Iphone Xs", phone: "001-12193-1219"}
}
})
}
fetchPost(){
const URL = 'http://facicla:5000/api';
return fetch(URL, {method:'GET',headers:new Headers ({
'Accept': 'application/json',
'Content-Type': 'application/json',
})})
.then(response => Promise.all([response, response.json()]));
}
Render
render() {
const { shippings, addNewData} = this.state;
return (
<div className="wrapper">
<div className="row row-eq-height">
{shippings.map((shipping, key) => (
<div className="col-sm-3 col-md-3 col-lg-3" key={key}>
<div className="d-flex justify-content-between">
<h5 className="fw-bold">{shipping.name}</h5></a>
<h5 className="fw-bold">{shipping.phone}</h5></a>
</div>
</div>
))}
</div>
}
Try this:
fetchAllData(){
return this.fetchPost().then(([response,json]) => {
if(response.status === 200)
{
console.log(json.data.shipping)
this.setState(
{ shippings: Object.values(json.data.shipping)
//or shippings: json.data.shipping
}
)
//0: { name: "Samsung A10", phone: "001-2342-23429"}
//1: {name: "Iphone Xs", phone: "001-12193-1219"}
}
})
}
Related
I am trying to add a "sorting" system to a clothing website I am building. The issue I am having is that whenever a new parameter is being added, it removes the old one added. I would guess the reason is that the variable holding the parameters are being re-rendered whenever you sort the products.
Here is my code:
const FetchAPI = (props) => {
const [product, setProducts] = useState([]);
// Key and Value
let facetKey = props.facetKey;
let facetValue = props.facetValue;
let params = {
store: "US",
offset: props.offset,
categoryId: props.categoryId,
limit: props.limit,
country: "US",
sort: "freshness",
currency: "USD",
sizeSchema: "US",
lang: "en-US",
};
if (facetKey) {
params = { ...params, offset: 0, limit: 0, [facetKey]: facetValue };
}
useEffect(() => {
const options = {
method: "GET",
url: "https://asos2.p.rapidapi.com/products/v2/list",
params: params,
headers: {
"x-rapidapi-key": "",
"x-rapidapi-host": "",
},
};
axios
.request(options)
.then(function (response) {
setProducts(response.data.products);
props.items(response.data.itemCount);
props.facets(response.data.facets);
})
.catch(function (error) {
console.error(error);
});
}, [props.limit, facetValue]);
return (
<div>
<div className={classes.container}>
{product.map((product) => (
<ProductCard
key={product.id}
img={product.imageUrl}
name={product.name}
price={product.price.current.text}
/>
))}
</div>
</div>
);
};
The re-rendering of params occurs because it is inside of the const FetchAPI, but I am not that sure how I can "ignore" that and make the params keep the first value. Perhaps could I solve this by putting the values in localstorage? Or is there a better way?
I am trying to pass below data to the laravel backend:
form: new Form( {
name: '',
file2: null,
licenses: [
{name: '', xerox: null},
{name: '', xerox: null},
]
}),
I am facing laravel validation problem. Like, if I tried to send data with the help of FormData() then php received the array and can validate the data except array element (i.e. Licenses) which also contains the attached files in an array of objects.
On backend side, it receives like below image. It doesn’t shows attached licenses images, except the profile image.
Below are the codes details also includes the repo of the project, if it needed.
Could you please tell me how could I sent the data with the attachment to the server?
Example-component.vue
<template>
<b-form #submit.prevent="onSubmit" #keydown="form.errors.clear($event.target.name)">
<b-form-group id="input-group-2" label="Your Name:" label-for="input-2">
<b-form-input
id="input-2"
v-model="form.name"
placeholder="Enter name"
></b-form-input>
</b-form-group>
<input type="file" id="file" ref="file" v-on:change="handleFileUpload()" class="mb-3"/>
<!--License-->
<b-form-group label="License details(if applicable):" class="">
<b-form-group v-for="(l, index) in form.licenses" :key="l.index" align-v="center" class="">
<b-card bg-variant="light">
<b-form-group>
<b-form-input id="input-license1" v-model="l.name" placeholder="Enter your License name:" class=""></b-form-input>
</b-form-group>
<b-form-group>
<input
type="file"
id="filelicense"
name="xerox"
ref="licenseFile"
v-on:change="handleLicenseFileUpload($event.target.name, $event.target.files[0], index)"
class="mb-3"/>
<div>Selected file: {{ l.xerox ? l.xerox.name : '' }}</div>
</b-form-group>
</b-card>
</b-form-group>
</b-form-group>
<b-button type="submit" variant="primary">Submit</b-button>
</b-form>
</template>
<script>
import Form from "../core/Form";
export default {
data() {
return {
form: new Form( {
name: '',
file2: null,
licenses: [
{name: '', xerox: null},
{name: '', xerox: null},
]
}),
isLoading: false
}
},
methods: {
handleLicenseFileUpload(fieldName, SelectedFile, index) {
console.log(SelectedFile);
this.form.licenses[index].xerox = SelectedFile;
},
onSubmit() {
this.isLoading = true;
this.form.post('/candidates')
.then(response => {
this.response = response
console.log(response.data.message)
})
.catch((err) => {
})
.finally(() => {
this.isLoading = false
})
},
handleFileUpload(){
this.form.file2 = this.$refs.file.files[0];
}
},
mounted() {
console.log('Component mounted.')
}
}
</script>
CandidateController.php
public function store(Request $request)
{
$data = $request->validate([
'name' => 'required',
'file2' => '',
'licenses.*.name' => 'required',
'licenses.*.xerox' => 'required',
]);
dd($request->all());
Form.js
courtesy
import Errors from './Errors';
class Form {
constructor(data) {
this.originalData = data;
for (let field in data) {
this[field] = data[field];
}
this.errors = new Errors();
}
data() {
let data = {};
for (let property in this.originalData) {
data[property] = this[property];
}
return data;
}
setFormData(data) {
let formData = new FormData();
for (let field in data) {
formData.append(field, data[field]);
}
return formData;
}
reset() {
for (let field in this.originalData) {
this[field] = '';
}
this.errors.clear();
}
post(url) {
return this.submit('post', url);
}
submit(requestType, url) {
let config = {
headers: {
Authorization: 'sometoken',
'Content-Type': `multipart/form-data; boundary=${Math.random().toString().substr(2)}`,
}
}
return new Promise((resolve, reject) => {
axios[requestType](url, this.setFormData(this.data()))
.then(response => {
this.onSuccess(response.data);
resolve(response.data);
})
.catch(error => {
this.onFail(error.response.data.errors);
reject(error.response.data);
});
});
}
onSuccess(data) {
//alert(data.message); // temporary
this.reset();
}
onFail(errors) {
this.errors.record(errors);
}
}
export default Form;
I ask for your help in writing the conditions for selecting an object in JSON.stringify ().
How can i do this?
this.props.a > 7;
this.props.b > 7
onSubmit = (e) => {
e.preventDefault();
this.props.x(this.state.y);
const user1 = {
name: "John",
age: 30
};
const user2 = {
name: "Vasya",
age: 27
}
fetch('URL', {
method: 'POST',
headers: {
'Content-Type': 'application/json;charset=utf-8'
},
body:JSON.stringify (How can I write something with a similar meaning
this.props.a>7 ? USER1:USER2 )
});
}
How about
body: ( this.props.a>7 ? JSON.stringify(USER1) : JSON.stringify(USER2) )
So I have to make a post request without a form or a button. I have the patientInfo array that is rendered on a table. When the user chooses a location for a patient, then that patient will have a timestamp value. When the patient in the array has a timestamp that's when I am supposed to auto post the patient with the timestamp.
My handleAutoObsSubmit() is kinda working but the problem is, it maps over the patienArray and sends the patient multiple time so if the user chooses the third patient's location, there will be three object of the same patient that is sent.
Another issue I am having with is componentDidUpdate, it sends the post request every second. I suspect that is because the patient count is being count down every sec. Not 100% sure though. Is it even a good idea to send post request in componentDidUpdate?
patientInfo = [
{ count: 100, room: "1", name: 'John Nero', timeStamp: '', location: ''},
{ count: 100, room: "2", name: 'Shawn Michael', timeStamp: '', location: ''},
{ count: 100, room: "3", name: 'Gereth Macneil', timeStamp: '', location: ''}
]
handleAutoObsSubmit = () => {
const postUrl = '/send_patient_that_has_timeStamp';
const timeStampedPatients = this.state.patientInfo.filter(patient => patient.timeStamp !== '');
let data = {};
timeStampedPatients.map((patient) => {
data = {
room: patient.room,
patient: patient.name,
timestamp: patient.timeStamp,
location: patient.locationInfo,
};
});
fetch(postUrl, {
method: 'POST',
body: JSON.stringify(data),
headers: {
'Content-Type': 'application/json'
}
})
.then((res) => {
if (!res.ok) {
console.log('request failed');
} else {
console.log('request sent');
}
});
}
componentDidUpdate() {
this.state.patientInfo.map(patient => {
if (patient.timeStamp !== '') {
this.handleAutoObsSubmit();
}
});
}
componentDidMount() {
this.countDownInterval = setInterval(() => {
this.setState(prevState => ({
patientInfo: prevState.patientInfo.map((patient) => {
if (patient.locationInfo!== '') {
if (patient.count <= 0) {
clearInterval(this.countDownInterval);
}
return { ...patient, count: patient.count - 1 };
}
return patient;
})
}));
}, 1000);
}
You should be able to handle it in a similar fashion to this:
function Table() {
const [tableData, setTableData] = React.useState([
{
name: "John Doe",
timestamp: ""
},
{
name: "Jane Doe",
timestamp: ""
},
{
name: "Nancy Doe",
timestamp: ""
}
]);
const updateItem = (event, index) => {
let newstate = [...tableData];
newstate[index].timestamp = (new Date(Date.now())).toString();
alert(`Do POST here: ${JSON.stringify(newstate[index],null,2)}`);
setTableData(newstate);
};
return (
<table border="5">
<tr>
<th>
<div>Patient</div>
</th>
<th>
<div>Timestamp</div>
</th>
<th>Update</th>
</tr>
{tableData.map((item, index) => {
return (
<tr>
<td>{item.name}</td>
<td style={{width:'410px'}}>{item.timestamp}</td>
<td>
<button
style={{backgroundColor:'green', color:'white'}}
onClick={event => updateItem(event, index)}>
UPDATE
</button>
</td>
</tr>
);
})}
</table>
);
}
ReactDOM.render(<Table />, document.body);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.9.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.6/umd/react-dom.production.min.js"></script>
I am using React and the Pokemon API (https://pokeapi.co/) to make a simple web app where the user can search pokemons by name and filter by type.
I successfully implemented the searching for my own data.
constructor() {
super();
this.state = {
contactData: [
{ name: 'Abet', phone: '010-0000-0001' },
{ name: 'Betty', phone: '010-0000-0002' },
{ name: 'Charlie', phone: '010-0000-0003' },
{ name: 'David', phone: '010-0000-0004' }
]
};
}
With the contactData that I have, I successfully search the data that contains the keyword.
render() {
const mapToComponents = (data) => {
//data.sort();
data = data.filter(
(contact) => {
return contact.name.toLowerCase()
.indexOf(this.state.keyword.toLowerCase()) > -1;
}
)
return data.map((contact, i) => {
return (<ContactInfo contact={contact} key={i}/>);
});
};
return(
<div className="Home">
<input
name = "keyword"
placeholder = "Search"
value = { this.state.keyword }
onChange = { this.handleChange }
/>
<div className="info">{ mapToComponents(this.state.contactData)}</div>
</div>
)
}
My question is, I am not sure how to do the same thing with my response data from the Pokemon API. My response data looks like this in the console:
{count: 811, previous: null, results: Array(20), next: "https://pokeapi.co/api/v2/pokemon/?offset=20"}
count
:
811
next
:
"https://pokeapi.co/api/v2/pokemon/?offset=20"
previous
:
null
results
:
Array(20)
0
:
{url: "https://pokeapi.co/api/v2/pokemon/1/", name: "bulbasaur"}
1
:
{url: "https://pokeapi.co/api/v2/pokemon/2/", name: "ivysaur"}
2
:
{url: "https://pokeapi.co/api/v2/pokemon/3/", name: "venusaur"}
3
:
{url: "https://pokeapi.co/api/v2/pokemon/4/", name: "charmander"}
4
:
{url: "https://pokeapi.co/api/v2/pokemon/5/", name: "charmeleon"}
5
:
{url: "https://pokeapi.co/api/v2/pokemon/6/", name: "charizard"}
6
:
{url: "https://pokeapi.co/api/v2/pokemon/7/", name: "squirtle"}
7
:
{url: "https://pokeapi.co/api/v2/pokemon/8/", name: "wartortle"}
8
:
{url: "https://pokeapi.co/api/v2/pokemon/9/", name: "blastoise"}
9
:
{url: "https://pokeapi.co/api/v2/pokemon/10/", name: "caterpie"}
10
:
{url: "https://pokeapi.co/api/v2/pokemon/11/", name: "metapod"}
11
:
{url: "https://pokeapi.co/api/v2/pokemon/12/", name: "butterfree"}
12
:
{url: "https://pokeapi.co/api/v2/pokemon/13/", name: "weedle"}
13
:
{url: "https://pokeapi.co/api/v2/pokemon/14/", name: "kakuna"}
14
:
{url: "https://pokeapi.co/api/v2/pokemon/15/", name: "beedrill"}
15
:
{url: "https://pokeapi.co/api/v2/pokemon/16/", name: "pidgey"}
16
:
{url: "https://pokeapi.co/api/v2/pokemon/17/", name: "pidgeotto"}
17
:
{url: "https://pokeapi.co/api/v2/pokemon/18/", name: "pidgeot"}
18
:
{url: "https://pokeapi.co/api/v2/pokemon/19/", name: "rattata"}
19
:
{url: "https://pokeapi.co/api/v2/pokemon/20/", name: "raticate"}
length
:
20
__proto__
:
Array(0)
__proto__
:
Object
How can format this like the contactData that I've created and display it for searching?
First you need one method to fetch data from API like this:
loadData() {
fetch('https://pokeapi.co/api/v2/pokemon/')
.then(result => result.json())
.then(items => this.setState({ data: items })
}
Then create another method componentDidMount and pass loadData():
componentDidMount() {
this.loadData()
}
From official React documentation:
componentDidMount() is invoked immediately after a component is
mounted. Initialization that requires DOM nodes should go here. If you
need to load data from a remote endpoint, this is a good place to
instantiate the network request. Setting state in this method will
trigger a re-rendering.
More information here: React Components
JSFiddle example:
class Data extends React.Component {
constructor(props) {
super(props);
this.state = {
data: []
};
}
componentDidMount() {
this.loadData()
}
// Fetch data from API:
loadData() {
fetch(`https://pokeapi.co/api/v2/pokemon/`)
.then(result => result.json())
.then(items => this.setState({data: items}))
}
render() {
const mapToComponents = data => {
// Your logic...
// Here you can use data...
};
return (
<div>
<h1>Pokemon's:</h1>
<ul>
{this.state.data.results !== undefined ?
this.state.data.results.map((x, i) => <li key={i}>{x.name}</li>)
: <li>Loading...</li>
}
</ul>
<h1>THIS.STATE.DATA:</h1>
<pre>
{JSON.stringify(this.state.data, null, 2)}
</pre>
</div>
);
}
}
ReactDOM.render(
<Data />,
document.getElementById('container')
);
<div id="container">
<!-- This element's contents will be replaced with your component. -->
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>