Displaying data from json as suggestions under a searchbar in reactjs - json

I have a component called AutoFill which looks like this,
const AutoFill = (props) => {
console.log('proppppppsss', props)
const results = props.results || []
return (
<ul>
{results.map(({ name, href }) => (
<li key={href}>
<a href={href} target='_blank' rel='noopener noreferrer' key={href}>
{name}
</a>
</li>
))}
</ul>
)
}
The Json File where data gets passed through looks like this,
[
{
"a": {
"apple": {
"name": "apple",
"href": "https://www.apple.com/"
},
"armadillo": {
"name": "armadillo",
"href": "https://www.armadillo.com/"
}
},
"b": {
"box": {
"name": "box",
"href": "https://www.box.com/"
},
"berserk": {
"name": "berserk",
"href": "https://www.berserk.com/"
}
}
}
]
The fetch that gets the data from the json
import fetch from 'isomorphic-fetch'
const FetchAndParseResults = (url) => {
return fetch(url).then(response => {
const parsedJson = response.json()
return parsedJson
})
}
export default FetchAndParseResults
The search that makes use of the autofill
import AutoFill from './autofill'
import PropTypes from 'prop-types'
export default class Searchbar extends React.Component {
constructor (props) {
super(props)
this.state = {
className: Styles.input,
icon: Styles.icon__wrapper,
value: []
}
this.input = React.createRef()
}
openInput = () => {
this.setState({
className: Styles.input__active,
icon: Styles.iconWidth
}, () => {
this.input.focus()
})
this.props.onOpen && this.props.onOpen()
}
closeInput = () => {
this.setState({
className: Styles.input,
icon: Styles.icon__wrapper
})
this.props.onClose && this.props.onClose()
}
handleChange = event => {
let value = event.target.value
this.setState({ value })
this.props.performSearch(value)
}
handleSubmit = event => {
event.preventDefault()
}
render () {
console.log('results', this.props.results)
console.log('state.value', this.state.value)
return (
<div>
<form onSubmit={this.handleSubmit} className={Styles.search}>
<div className={this.state.icon}>
<Icon className={Styles.icon__wrapper} iconName='faSearch' onClick={this.openInput} />
</div>
<Search autoComplete='off' value={this.state.value} onChange={this.handleChange} id='search' tabIndex='0' myref={input => { this.input = input }} className={this.state.className} onBlur={this.closeInput} placeholder='Search' />
</form>
<div>
<AutoFill results={this.props.results} />
</div>
</div>
)
}
}
Search.propTypes = {
performSearch: PropTypes.func,
results: PropTypes.array
}
the searchContainer that makes use of everything
import React from 'react'
import Searchbar from './index.js'
import FetchAndParseResults from './FetchAndParseResults.js'
class SearchContainer extends React.Component {
state = {
results: []
}
performSearch = event => {
return FetchAndParseResults('static/autofill.json').then(data => {
this.setState({ results: data })
})
}
render () {
return (
<Searchbar
performSearch={this.performSearch}
results={this.state.results}
/>
)
}
}
export default SearchContainer
At <a href={href} target='_blank' rel='noopener noreferrer' key={href}>{name}</a>
the data of the names should be displayed but instead of the names i get this,
https://gyazo.com/647176b09afcd55b4238f7975c0e7488
An empty unordered list.
Therefore help would be highly appreciated,
and looked into.

Related

React get inner JSON object from api

Update: How do I get an array (currentSchedule) within an array (response)?
I am trying to get the JSON object in "response" within the JSON code below. For instance, I want to get the title & description in "response", but it is not returning anything for me with the codes that I implemented below.
all.json
{"responseCode":200,
"responseMessage":"Channel Listing",
"response":[{
"id":395,
"title":"Title 1",
"description":"Description 1",
"currentSchedule":[{"eventId":"123456","title":"Hello Title"]}
}]
}
App.js
class App extends Component {
constructor(props){
super(props);
this.state = {
items: [],
isLoaded: false,
}
}
componentDidMount(){
fetch('/all.json')
.then(res => {
res.json()
})
.then(json => {
this.setState({
isLoaded: true,
items: [],
})
});
}
render() {
var { isLoaded, items } = this.state;
if(!isLoaded) {
return <div>Loading...</div>;
}
else {
return (
<div className="App">
<ul>
{items.map(item => (
<li key={item.id}>
Title: {item.title} | Description: {item.description}
</li>
))};
</ul>
</div>
);
}
}
}
export default App;
You need to assign response in your setState to view it, somthing like this
componentDidMount(){
fetch('/all.json')
.then(res => res.json())
.then(json => {
this.setState({
isLoaded: true,
items: json.response,
})
}).catch(console.log);
}

Why is my input field not allowing me to edit the content?

I cannot change the value of this input field in the browser.
<div>
cart.products.map((item) => (
<div className="" key={item.product._id}>
<div
className={`${styles.quantity} col-6 d-flex justify-content-around align-items-center col-md-2
d-md-block mb-2 mb-md-0`}>
<input
className="form-control-sm text-center mb-2"
type="number"
name="quantity"
value={item.quantity}
onChange={(event) => handleChange(event.target)}
/>
</div>
</div>
)
</div>;
The cart data looks like this and is being pulled from redux;
{
"_id": {
"$oid": "5f15ee2c0b94bf240470d70d"
},
"user": {
"$oid": "5f15ee2c0b94bf240470d70c"
},
"products": [
{
"quantity": 2,
"_id": {
"$oid": "5f47d8f2a0c7f4238cb82bf6"
},
"product": {
"$oid": "5f1864917c213e0f5779ee48"
}
},
}
handleChange:
const handleChange = (event.target) => {
const { name, value } = event.target;
setQuantity(value);
};
Make a deep copy of the cart from the reducer thereby giving the component its own copy of the cart;
useEffect(() => {
getCart(cartIn);
}, [cartIn]);
const [cart, setCart] = useState({});
const getCart = (cart) => {
setCart(JSON.parse(JSON.stringify(cart)));
};
Reducer code:
export const CartReducer = (state = initialState, { type, payload }) => {
switch (type) {
case ReducerTypes.SET_CART:
console.log("cart", payload);
const subtotal = computeSubtotal(payload);
addCartToLocalStorage(payload, subtotal);
return {
...state,
cart: payload,
subtotal: subtotal,
numberOfItems: payload.products.length,
};
}
};
Destructuring example using event.target:
const handleChange = (event) => {
const { name, value } = event.target;
setUserData((prevState) => ({ ...prevState, [name]: value }));
};

convert json data to react components with ajax requests

I have a problem in convertion json data to react components with ajax requests.
My json file is under "src/data/form-inputs.json".
The content of form-inputs.json is
{
"form_inputs": [
{
"label": "Sender Email",
"name": "sender_mail",
"type": "email",
"value": null,
"rules": "required|min:3|max:64",
"options": [],
"default_value": null,
"multiple": false,
"readonly": false,
"placeholder": "Sender Email",
"info": "Example value of how to fill the input"
}
]
}
Under "src/components/form.js" is form.js file that converts json data to React.js components. The code of form.js is
import React, { Component } from 'react';
class Form extends Component {
constructor(props) {
super(props);
this.state = {
isLoaded: false,
form_inputs: []
};
}
componentDidMount() {
fetch('../test-json/form-inputs.json')
.then(res => res.json())
.then(
(result) => {
this.setState({
isLoaded: true,
form_inputs: result.form_inputs
});
});
}
render() {
const {isLoaded, form_inputs} = this.state;
if(!isLoaded) {
return <div>Loading...</div>
}else{
return (
<div>
<ul>
{form_inputs.map(form_input => (
<li>
{form_input.label}
</li>
))}
</ul>
</div>
)
}
}
}
export default Form
Please can somebody help me with this problem?
Thank you very much in advance!
Import your json file. No need it parse it, javascript interpreter will automatically parse it for you. You don't need a state anymore in your component. Just loop in the imported json.
import React from "react";
import ReactDOM from "react-dom";
import formData from "./formData.json";
function App() {
return (
<div className="App">
<ul>
{formData.form_inputs.map(form_input => (
<React.Fragment>
<label for={form_input.label}>{form_input.label}</label>
<input
key={form_input.label}
id={form_input.label}
type={form_input.type}
name={form_input.name}
defaultValue={form_input.default_value}
placeholder={form_input.placeholder}
/>
</React.Fragment>
))}
</ul>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Here is a codesandbox link to see it in action.

How can i put the data array gained from the fetch return to the Dropdown component?

I'm trying to make a simple dropdown list which data is gained from a fetch return..
if I use console to view the return, it shows like this :
[
{
"ID": "BOGOR~10"
"Location": "BOGOR"
},
{
"ID": "JADETABEK~16"
"Location": "JADETABEK"
}
]
if I want to take the location BOGOR and JADETABEK and put them into a Dropdown, how can I do that? this is my testing class
import React , { Component } from 'react';
import { View , StyleSheet , Text , Dimensions } from 'react-native';
import { Dropdown } from 'react-native-material-dropdown';
const ScreenWidth = Dimensions.get('window').width;
const Screenheight = Dimensions.get('window').height;
export default class testing extends Component {
constructor(props) {
super(props)
this.state = {
data: []
}
}
componentDidMount() {
fetch(url , {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({"lokasi":
{
}
})
})
.then(response => response.json())
.then(res => {
this.setState({
data: res.PilihLokasiResult.Lokasi
})
alert(res.PilihLokasiResult.Lokasi)
})
}
render() {
return(
<View style={styles.container}>
<View>
<Text>{this.state.location}</Text>
<Dropdown label="select location" style={{width: 400 }}/>
</View>
</View>
)
}
}
You need to format the data since react-native-material-dropdown accepts data in the form of {value: 'Sample'}
this.state = {
data: [],
dropDownData: []
}
const formatData = (data) => {
return data.map(dataObj => {
return {value: dataObj.Location} // return based on location
})
}
.then(res => {
const dropDownData = formatData(res.PilihLokasiResult.Lokasi)
this.setState({
data: res.PilihLokasiResult.Lokasi,
dropDownData
})
})
<Dropdown label="select location" data={this.state.dropDownData} style={{width: 400 }}/>

What is the best way to construct a dropdown and fetch JSON data dynamically from a URL

My dropdown has three Items ===> Item0,Item1,Item2 .
Every time I select a particular item, I would like to fetch the JSON data and display it on the page (on IOS). I do not understand where exactly to define the onPress event for the Dropdown.
Any help would be appreciated.
const leveldata = [
{ value: 'level1', props: { disabled: true } },
{ value: 'level2' },
{ value: 'level3' },
];class TopScores extends Component {
constructor(props) {
super(props);
this.onChangeText = this.onChangeText.bind(this);
this.state = {
data: [],
};
}
onChangeText() {
if (leveldata.value === 'leve1') {
fetch('url')
.then((response) => response.json())
.then((responseData) => {
this.setState({
newdata: responseData.newdata,
});
})
.done();
} else if (leveldata.value === 'level2') {
fetch('url1')
.then((response) => response.json())
.then((responseData) => {
this.setState({
newdata: responseData.newdata,
});
})
.done();
}
}
render() {
console.log('data:', this.state.data);
return (
<View>
<View style={styles.container1}>
<Image
/* eslint-disable global-require */
source={require('../Images/Top.png')}
/* eslint-enable global-require */
/>
<Text style={styles.Text1}> Top Contenders</Text>
</View>
<View>
<Dropdown
data={leveldata}
label='Level'
onChangeText={this.onChangeText}
/>
</View>
</View>
);
}
}
If I remember correctly you need to add the onChangeText prop.
import React, { Component } from 'react';
import {
Text,
View,
StyleSheet,
Image
} from 'react-native';
import { Dropdown } from 'react-native-material-dropdown';
const leveldata = [
{ value: 'level1', props: { disabled: true } },
{ value: 'level2' },
{ value: 'level3' }
];
class TopScores extends Component {
constructor(props) {
super(props);
this.onChangeText = this.onChangeText.bind(this);
this.state = {
data: []
};
}
onChangeText(text) {
if(text === 'leve1'){
fetch('url')
.then((response) => response.json())
.then((responseData) => {
this.setState({
newdata: responseData.newdata,
});
})
.done();
}
}
render() {
return (
<View>
<Dropdown
data={leveldata}
label='Level'
onChangeText={this.onChangeText} />
</View>
);
}
}