Currently I am working on a React app with a search function trying to fetch JSON data and displaying a matched search result on the website
import { React, useState } from 'react';
export default function PractitionerSearch() {
const [data, setData] = useState([]);
const [name, setName] = useState("");
const handleSubmit = async (event) => {
event.preventDefault();
try {
const res = await fetch("http://localhost:8080/practitioners", {
method: "GET",
headers: { "Accept": "application/json" }
})
.then(response => response.json())
.then(response => { console.log(response); });
if (!res) {
return Error(`Error! status: ${res}`);
} else if (res.status === 200) {
return res
}
const data = await res.json();
setData(data);
} catch (error) {
console.log(error);
}
};
const filtered = data.filter((practitioner) =>
data.includes(practitioner.address[1])
);
return (
<div className="App" style={{ padding: '20px' }}>
<label className='form-label' htmlFor='name'>
Practitioner Name:
</label>
<form onSubmit={handleSubmit}>
<input
type="text"
placeholder="Search..."
id='name'
value={name.name}
onChange={(event) => setName({
...name,
[event.target.name]: event.target.value,
})}
/>
<button className="search__button" type='Submit'>
Search
</button>
</form>
<ul>
{filtered.map((practitioner) => {
return <li>{practitioner.name}</li>;
})}
</ul>
</div>
);
}
and here's an example of the JSON
"practitioners": [
{
"address": [
{
"addr1": "12 W 12 Dr",
"addr2": "",
"city": "Moon",
"fax": "",
"insurances": [],
"isPrimary": "false",
"phone": "5555555555",
"state": "PA",
"zip": "55555"
},
{
"addr1": "13 W 13 Dr",
"addr2": "",
"city": "North Pole",
"fax": "",
"insurances": [],
"isPrimary": "false",
"phone": "8888888888",
"state": "ND",
"zip": "88888"
},
{
"addr1": "14 W 14 Dr",
"addr2": "",
"city": "Somewhereville",
"fax": "",
"insurances": [],
"isPrimary": "true",
"phone": "2222222222",
"state": "AZ",
"zip": "88888"
}
],
"credential": [
"PT",
"DPT"
],
"first_name": "DAVE",
"gender": "m",
"last_name": "JONES",
"npi": "2342143124",
"specialty": [
"Physical Therapist"
]
},
When I console log the response, I get...
(25) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]
0
:
{address: Array(3), credential: Array(2), first_name: 'JOY', gender: 'f', last_name: 'SCOTT', …}
But not getting anything displayed on the page
Got it sorted out! Below is the updated code:
export default function PractitionerSearch() {
const [data, setData] = useState([]);
const [name, setName] = useState("");
const handleSubmit = async (event) => {
event.preventDefault();
try {
fetch("http://localhost:8080/practitioners", {
method: "GET",
headers: { "Accept": "application/json" }
})
.then(response => response.json())
.then(response => setData(response))
.then(response => { console.log(response); });
} catch (error) {
console.log(error);
}
};
console.log("dataState", data);
const filtered = data.filter((practitioner) =>
practitioner.first_name.includes(name)
);
console.log("filtered", filtered)
return (
<div className="App">
<label className='form-label' htmlFor='name'>
Practitioner Name:
</label>
<form onSubmit={handleSubmit}>
<input
className="form-input"
type="text"
placeholder="Search..."
id='name'
value={name}
onChange={(event) => setName(
event.target.value
)}
/>
<button className="search-button" type='Submit'>
Submit
</button>
</form>
<div>
<ul className="map">
{filtered.map((practitioner, index) => {
console.log(practitioner);
return <li key={index}>{practitioner.first_name}</li>;
})}
</ul>
</div>
</div>
);
}
This line:
.then(response => { console.log(response); });
should be:
.then(response => setData(response))
Related
I'm trying to display student data and the courses they are enrolled in from a a simple API I made.
Here's the result from the API https://localhost:44309/api/Students
[
{
"id": 1,
"lastName": "Rizal",
"firstName": "Jose",
"courses": [
"C#",
"Javascript",
"CSS"
]
},
{
"id": 2,
"lastName": "Bonifacio",
"firstName": "Andres",
"courses": [
"HTML",
"ASP.NET MVC"
]
},
{
"id": 3,
"lastName": "Sora",
"firstName": "Tandang",
"courses": [
"CSS",
".NET"
]
}
]
Here's my Javascript code
import React from "react"
import { useState, useEffect } from "react";
const StudentList = () => {
const [students, setStudent] = useState([]);
const getData = async () => {
const response = await fetch("https://localhost:44309/api/students");
const data = await response.json()
setStudent(data)
}
useEffect(() => {
getData()
}, []);
return (
<div className="student-list">
<h2>Students and their courses</h2>
{students.map(student => (
<div className="student-preview" key={student.id}>
<p>{ student.fname } { student.lname }</p>
<p>{ student.courses }</p>
</div>
))}
</div>
)
}
export default StudentList
I'm getting an error saying
Uncaught ReferenceError: students is not defined
I wonder what I'm doing wrong.
Something is wrong with your api the code works fine with static data
import React from "react";
import { useState, useEffect } from "react";
const StudentList = () => {
const [students, setStudent] = useState([
{
id: 1,
lastName: "Rizal",
firstName: "Jose",
courses: ["C#", "Javascript", "CSS"]
},
{
id: 2,
lastName: "Bonifacio",
firstName: "Andres",
courses: ["HTML", "ASP.NET MVC"]
},
{
id: 3,
lastName: "Sora",
firstName: "Tandang",
courses: ["CSS", ".NET"]
}
]);
return (
<div className="student-list">
<h2>Students and their courses</h2>
{students.map((student) => (
<div className="student-preview" key={student.id}>
<p>
{student.fname} {student.lname}
</p>
<p>{student.courses}</p>
</div>
))}
</div>
);
};
export default StudentList;
Working on a little project of mine and ran into an issue.
I am using the "ASOS" API and I need to dynamically add key and value to the parameters that it needs to find the correct product. It is to pick for example color, size, price range etc. Issue is, all things I've tried haven't ended up in a success.
How do I dynamically add key and value to an object?
Something like this:
currency: "USD",
sizeSchema: "US",
lang: "en-US",
newKey: newValue
Here is my code:
const FetchAPI = (props) => {
const [product, setProducts] = useState([]);
// Key and Value
let facetKey = props.facetKey;
let facetValue = props.facetValue;
// Sets the paramaters
let params = {
store: "US",
offset: props.offset,
categoryId: props.categoryId,
limit: props.limit,
country: "US",
sort: "freshness",
currency: "USD",
sizeSchema: "US",
lang: "en-US",
};
// Need to add my "facetKey" and "facetValue" to "params".
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);
console.log(response.data.facets);
})
.catch(function (error) {
console.error(error);
});
}, [props.offset, props.limit]);
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>
);
};
Thanks!
Keep in mind
The facetKey and facetValue return string values, and if the user havent picked a "facet", or an option to filter the products. Then it returns undefined, can of course change this to null.
You can use the [] operator with objects.
In general:
let obj = {};
let key = 'x';
let value = 3;
obj[key] = value;
console.log(obj);
console.log(obj[key]);
In your example:
let facetKey = props.facetKey;
let facetValue = props.facetValue;
// Sets the paramaters
let params = {
// ...
};
// Need to add my "facetKey" and "facetValue" to "params".
if (facetKey)
params[facetKey] = facetValue;
You can write the code as follows.
let params = {
store: "US",
offset: props.offset,
categoryId: props.categoryId,
limit: props.limit,
country: "US",
sort: "freshness",
currency: "USD",
sizeSchema: "US",
lang: "en-US",
[facetKey]: facetValue
};
And if facetKey can be undefined, you can do like this.
let params = {
store: "US",
offset: props.offset,
categoryId: props.categoryId,
limit: props.limit,
country: "US",
sort: "freshness",
currency: "USD",
sizeSchema: "US",
lang: "en-US",
};
facetKey && params = { ...params, [facetKey]: facetValue }
// or
if (facetKey) {
params = { ...params, [facetKey]: facetValue }
}
Hi everyone,
I have created a custom field plugin which is connectect to mapbox search API to get locations when the user types.
I have created the component and everything seems to be working fine until the part where I need to send the object to API.
When I want to store the location title in the API it works just fine
{
"id": 1,
"companyName": "Stina",
"location": "South Africa",
"published_at": "2021-02-25T22:31:14.550Z",
"created_at": "2021-02-25T22:29:18.335Z",
"updated_at": "2021-02-28T21:55:15.064Z",
}
So this is the code used to get that:
const updateLocationValue = (locationValue) => {
props.onChange({
target: { name: "location", value: locationValue.title },
});
};
But when I want to send the whole object so I can get the coordinates as well I get null
{
"id": 1,
"companyName": "Stina",
"location": null,
"published_at": "2021-02-25T22:31:14.550Z",
"created_at": "2021-02-25T22:29:18.335Z",
"updated_at": "2021-02-28T21:55:15.064Z",
}
This is the code that I use to send the whole object, and this works just fine in the console log and I am getting the coordinates as well but I can't pass it to Strapi:
const updateLocationValue = (locationValue) => {
props.onChange({
target: { name: "location", value: locationValue },
});
};
I am expecting to see an object just as below so I can get the title and coordinates:
{
"id": 1,
"companyName": "Stina",
"location": {object},
"published_at": "2021-02-25T22:31:14.550Z",
"created_at": "2021-02-25T22:29:18.335Z",
"updated_at": "2021-02-28T21:55:15.064Z",
}
I have registered the field in company.settings.json just as you can see below:
{
"kind": "collectionType",
"collectionName": "companies",
"info": {
"name": "Company",
"description": ""
},
"options": {
"increments": true,
"timestamps": true,
"draftAndPublish": true
},
"attributes": {
"companyName": {
"type": "string"
},
"location": {
"type": "locationsearch",
"columnType": "longtext"
},
"products": {
"collection": "product",
"via": "company"
}
}
}
So the columnType is longtext, I have tried to change it to "object" or "JSON" but it still shows me null
Here is the full code of the component which is working just fine:
import { Label, InputText } from "#buffetjs/core";
const apiToken =
"****************************************";
export default function Location(props) {
const [locationTitle, setLocationTitle] = useState("");
const [suggestions, setSuggestions] = useState([]);
const [suggestionsOpen, setSuggestionsOpen] = useState(false);
const wrapperRef = useRef(null);
const popperEl = useRef(null);
const [cursor, setCursor] = useState(null);
const fetchLocation = (searchText) => {
searchText &&
fetch(
`https://api.mapbox.com/geocoding/v5/mapbox.places/${searchText}.json?access_token=${apiToken}`
)
.then((response) => response.json())
.then((data) => {
const newSuggestions = data
? data.features.map((feature) => ({
title: feature.place_name,
centerCoordinates: feature.center,
}))
: [];
setSuggestions(newSuggestions);
});
};
useEffect(() => {
locationTitle && fetchLocation(locationTitle);
}, [locationTitle]);
useEffect(() => {
document.addEventListener("mousedown", handleClickOutside);
return () => {
document.removeEventListener("mousedown", handleClickOutside);
};
});
const updateLocationValue = (locationValue) => {
props.onChange({
target: { name: "location", value: locationValue.title },
});
};
const handleClickOutside = (e) => {
const { current: wrap } = wrapperRef;
if (wrap && !wrap.contains(e.target)) {
setSuggestionsOpen(false);
}
};
const setLocationValue = (location) => {
setLocationTitle(location.title);
updateLocationValue(location);
setSuggestionsOpen(false);
};
return (
<div ref={wrapperRef}>
<Label htmlFor="input">Location</Label>
<InputText
name="input"
onChange={(e) => setLocationTitle(e.target.value)}
placeholder="Riva 16, 21420, Bol, Croatia"
type="search"
value={locationTitle}
onClick={() => setSuggestionsOpen(true)}
/>
<div ref={popperEl} className="options-wrapper">
{suggestionsOpen && (
<div>
{suggestions.map((suggestion) => {
return (
<div
onClick={() => setLocationValue(suggestion)}
key={suggestion.id}
>
{suggestion.title}
</div>
);
})}
</div>
)}
</div>
</div>
);
}
Could anyone recommend any steps to finalize this?
Thanks a lot!
I am using React Native Picker.
I am calling an API which returns a list of State and City.
For now, there are two State: Kuala Lumpur (state: 14) and Selangor (state: 10)
state: 14 has two City: Kuala Lumpur (city: 262) and Sungai Besi (city: 263)
state: 10 has one City: Puchong (city: 256)
The JSON data looks like this:
{
"data": [
{
"city": "262",
"state": "14",
"city_desc": "Kuala Lumpur",
"state_desc": "Kuala Lumpur"
},
{
"city": "263",
"state": "14",
"city_desc": "Sungai Besi",
"state_desc": "Kuala Lumpur"
},
{
"city": "256",
"state": "10",
"city_desc": "Puchong",
"state_desc": "Selangor"
}
]
}
In my app, when I call the API, the Picker loads all the State and City.
However, is there anyway I can filter the State and City where I
ONLY want to show the City based on the State selected?
i.e. If I select state: 14, the picker should ONLY show city: 262 and city: 263
or If I select state: 10, the picker should ONLY show city: 256
IMPORTANT NOTE: For now there are only two State in the data BUT in the future I will be adding multiple State which will consists of multiple City each. For example: state: A will have 5 cities, state: B will have 3 cities etc.
Please do let me know if there's any efficient way of filter City based on State selected and as always all help would be highly appreciated.
Code snippet provided below:
class ClientScreen extends Component {
constructor(props) {
super(props);
this.state = {
pickerValueState: null,
dataState: [],
pickerValueCity: null,
dataCity: [],
isLoading: true,
}
}
componentDidMount() {
console.log('ComponentDidMount()');
this.apiStateCity();
}
apiStateCity() {
let self = this;
AsyncStorage.getItem('my_token').then((keyValue) => {
axios({
method: 'get',
url: Constants.API_URL + 'user_c/c_State_City/',
responseType: 'json',
headers: {
'X-API-KEY': Constants.API_KEY,
'Authorization': keyValue,
},
})
.then(function (response) {
console.log('apiStateCity Response: ', response.data.data);
self.setState({
dataState: response.data.data,
});
})
.catch(function (error) {
console.log('Error (1st): ', error);
});
}, (error) => {
console.log('Error (2nd): ', error) //Display error
});
}
stateList() {
return (
<View>
<Text>Select Location</Text>
<Text>State</Text>
<View>
<Picker
mode="dropdown"
selectedValue={this.state.pickerValueState}
onValueChange={(itemValue, itemIndex) => {
this.setState({ pickerValueState: itemValue });
console.log('State selected (itemValue): ', itemValue);
}}
>
{
this.state.dataState.map((item, key) => (
<Picker.Item label={item.state_desc} value={item.state} key={key} />)
)
}
</Picker>
</View>
</View>
);
}
cityList() {
return (
<View>
<Text>City</Text>
<View>
<Picker
mode="dropdown"
selectedValue={this.state.pickerValueCity}
onValueChange={(itemValue, itemIndex) => {
this.setState({ pickerValueCity: itemValue });
console.log('City selected (itemValue): ', itemValue);
}}
>
{
this.state.dataState.map((item, key) => (
<Picker.Item label={item.city_desc} value={item.city} key={key} />)
)
}
</Picker>
</View>
</View>
);
}
render() {
return (
<View>
<Text>BookingApp</Text>
<View>
{this.stateList()}
{this.cityList()}
{this.button()}
</View>
</View>
);
}
}
ScreenShot from the App:
var A = {
"data": [
{
"city": "262",
"state": "14",
"city_desc": "Kuala Lumpur",
"state_desc": "Kuala Lumpur"
},
{
"city": "263",
"state": "14",
"city_desc": "Sungai Besi",
"state_desc": "Kuala Lumpur"
},
{
"city": "256",
"state": "10",
"city_desc": "Puchong",
"state_desc": "Selangor"
}
]
};
let B= A.data.filter( item => item.state === '14');
console.log(B);
I have this state defined:
constructor(props){
super(props);
this.state = {
open: false,
customers:[],
customer:{},
products:[],
product:{},
orders:[],
order:{},
newForm:true,
phoneNumbererror:null,
shop:this.props.salon,
value:'a',
showTab:'none',
slideIndex: 0,
};
}
With the following function which contains a fetch, I recieve an array of objects with responseData.
getHistory(){
console.log("Log antes del fetch de customer id");
console.log(this.state.customer._id);
fetch(
DOMAIN+'/api/orders/customer/'+this.state.customer._id, {
method: 'get',
dataType: 'json',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization':'Bearer '+this.props.token
}
})
.then((response) =>
{
return response.json();
})
.then((responseData) => {
let orders = responseData.map((order) => {
return order.orderStatusChange ? Object.assign({}, order, {
status: order.orderStatusChange[0].status
}) : order;
});
this.setState({orders:orders});
console.log("Log del responseData");
console.log(responseData);
console.log(responseData.orderStatusChange[0]);
})
.catch(function() {
console.log("error");
});
}
This function is called in handleCellClick, where I pass some data from the consumer, such as the ID:
handleCellClick(y,x,row){
this.setState({
open:true,
slideIndex: 0,
newForm:false,
customer:{...row}
});
this.getProfiles();
this.getHistory();
}
The JSON object obtained from the fetch and kept within this.state.orders looks like this:
(29) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]
0:
created:"2017-07-06T15:58:07.958Z"
customer:"59561f3f1d178e1966142ad7"
lastModified:"2017-07-06T15:58:07.958Z"
orderList:[]
orderStatusChange:Array(1)
0:{status: "5", comments: "Creado en back antes de pagar", _id: "595e5e0f60fbf65149916b7c", created: "2017-07-06T15:58:07.958Z"}
length:1
__proto__:Array(0)
shop:"59108159bc3fc645704ba508"
totalAmount:4000
__v:0
_id:"595e5e0f60fbf65149916b7b"
__proto__:Object
As shown previously in the fetch, with this line this.setState({orders:responseData}) I can pass orders to the table where I want the id, date, status and price to be displayed:
<DataTables
height={'auto'}
selectable={false}
showRowHover={true}
columns={HISTORY_TABLE_COLUMNS}
data={this.state.orders}
showCheckboxes={false}
rowSizeLabel="Filas por página"
/>
The table called is:
const HISTORY_TABLE_COLUMNS = [
{
key: '_id',
label: 'Número de pedido',
style:{width: '37%'}
}, {
key: 'created',
label: 'Fecha del pedido',
style:{width: '33%'}
}, {
key: 'status',
label: 'Estado',
style:{width: '13%'}
}, {
key: 'totalAmount',
label: 'Total',
style:{width: '17%'}
}
];
How can I format the price (totalAmount) to have 2 decimals and print next to it the € symbol?
CAPTURE FOR BETTER UNDERSTANDING
This solution works fine with node module material-ui-datatables version 0.18.0
You can use render method in column settings to work on the column data.
const currencyToAppend = '€';
const HISTORY_TABLE_COLUMNS = [
{
....
}, {
....
}, {
key: 'totalAmount',
label: 'Total',
style:{width: '17%'}
render: (amount, all) => {
console.log(amount);
console.log(all);
return amount + ' ' + currencyToAppend;
}
}
];
While iterating data in table please do the following.
totalAmount.toFixed(2) + " €"
Update:
I would suggest this change should be done from backend, But any how for now you can handle it in map iterator where you are setting orders like following
const currencyToAppend = ' €';
let orders = responseData.map((order) => {
return order.orderStatusChange ? Object.assign({}, order, {
status: order.orderStatusChange[0].status
},{
totalAmount: order.totalAmount.toFixed(2) + currencyToAppend
}) : Object.assign({}, order, {
totalAmount: order.totalAmount.toFixed(2) + currencyToAppend
});
});
I hope this will solve your problem.
To complement #dev's answer, I'd suggest to have render the cell as a function as that gives you more control
Check out the codesandox demo https://codesandbox.io/s/0VVwq645L
const HISTORY_TABLE_COLUMNS = [
{
key: "_id",
label: "Número de pedido",
style: { width: "37%" },
value: item =>
<code>
{item._id}
</code>
},
{
key: "created",
label: "Fecha del pedido",
style: { width: "33%" },
value: item => <Time value={item.created} />
},
{
key: "status",
label: "Estado",
style: { width: "13%" },
value: item =>
<span>
{item.status}
</span>
},
{
key: "totalAmount",
label: "Total",
style: { width: "17%" },
value: item => <Amount value={item.totalAmount} currency="€"} />
}
];