convert json data to react components with ajax requests - json

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.

Related

React JSON is undefined

I'm fetching this JSON from an API:
{
"data": {
"email": "test#tre.com",
"inserted_at": "2021-03-30T15:37:06",
"links": [
{
"id": 1,
"title": "My link title",
"url": "http://google.com"
},
{
"id": 2,
"title": "My Youube title",
"url": "http://youtube.com"
}
]
}
}
I'm fetching it this way using Hooks:
export default function Notes() {
const [json, setJSON] = useState([]);
useEffect(() => {
fetch("http://localhost:4000/api/users/1", {
method: "GET"
})
.then((response) => response.json())
.then((json) => {
// console.log(data);
setJSON(json);
})
.catch((err) => {
console.error(err);
});
}, [setJSON]);
Then I try to show it like this:
return (
<>
<div className="content">
{JSON.stringify(json)}
<h1>{json.email}</h1>
</div>
</>
);
The line {JSON.stringify(json)} shows the JSON.
But the line <h1>{json.email}</h1> doesn't show anything.
I don't know why that happens and how can I access my variables.
Thanks . I appreciate any help
Is the data in the form of an array or an object?
You defined the initial state as and array ad hence you cannot do
// you can't do json.email if you expect the response as and array
const [json, setJSON] = useState([]);
change it to
const [json, setJSON] = useState({});
if it is an object. Then in the template do
{json.data && <h1>{json.data.email}</h1>}
<h1>{json.data && json.data.email}</h1>
instead of
<h1>{json.email}</h1>

React: Couldn't access properties within data after axios loads. Could it have something to do with params?

I'm coding MERN app and I'm almost done with it. However, I am having problems displaying a single customer page with data.
My App.js
import React from 'react';
import { BrowserRouter as Router, Route } from "react-router-dom";
import CustomersList from "./components/customers-list";
import customerRewards from './components/customerRewards';
import "bootstrap/dist/css/bootstrap.min.css";
function App() {
return (
<Router>
<div className="container">
<div className="header">
<h1>Wow Rewards Program</h1>
</div>
<Route path="/" exact component={CustomersList} />
<Route path='/:id' component={customerRewards} />
</div>
</Router>
);
}
export default App;
My Customer list Component to list customers in main page
import React, { Component } from 'react';
import axios from 'axios';
import CustomerCard from "./customerCard";
class CustomersList extends Component {
constructor(props) {
super(props);
this.state = {
customers: []
}
}
componentDidMount() {
axios.get('http://localhost:5000/customers/')
.then(response => {
this.setState({ customers: response.data });
})
.catch((error) => {
console.log(error);
})
}
render() {
const customers = this.state.customers;
console.log("customerList", customers);
let customersList;
if(!customers) {
customersList = "there is no customer record!";
} else {
customersList = customers.map((customer, k) =>
<CustomerCard customer={customer} key={k} />
);
}
return (
<div>
<h2>Customers List</h2>
<div>
<table>
<thead>
<tr>
<th>Account</th>
<th>Name</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{customersList}
</tbody>
</table>
</div>
</div>
)
}
}
export default CustomersList;
My CustomerCard Component to display each customer
import React from 'react';
import { Link } from 'react-router-dom';
const CustomerCard = (props) => {
const customerCard = props.customer;
return (
<tr>
<td>{customerCard.account}</td>
<td>{customerCard.name}</td>
<td>
<Link to={`/${customerCard.account}`}>view</Link>
</td>
</tr>
)
}
export default CustomerCard;
My Customer Rewards Component to list customer details
import React, { Component } from 'react';
import { Link} from 'react-router-dom';
import '../App.css';
import axios from 'axios';
class customerRewards extends Component {
constructor(props) {
super(props);
this.state = {
customerRewards: {}
};
}
componentDidMount() {
// const { accountId } = this.props.match.params;
console.log("Print id: " + this.props.match.params.id);
axios
.get('http://localhost:5000/customers/'+this.props.match.params.id)
.then(res => {
// console.log("Print-customerRewards-API-response: " + res.data);
this.setState({
customerRewards: res.data
})
})
.catch(err => {
console.log("Error from customerRewards");
})
};
render() {
const customerRewards = this.state.customerRewards;
console.log("customerID", customerRewards);
let CustomerItem = <div>
{customerRewards.purchase_history}
</div>
return (
<div >
<div className="container">
<div className="row">
<div className="col-md-10 m-auto">
<br /> <br />
<Link to="/" className="btn btn-outline-warning float-left">
Back
</Link>
</div>
<br />
<div className="col-md-8 m-auto">
<h1 className="display-4 text-center">Hello {customerRewards.name}</h1>
<p className="lead text-center">
{customerRewards.account}
</p>
<hr /> <br />
</div>
</div>
<div>
{ CustomerItem }
</div>
</div>
</div>
);
}
}
export default customerRewards;
this is my .json sample that I uploaded to MongoDB Atlas:
[
{
"account": "BCE456",
"name": "JohnDoe",
"purchase_history": [
{
"month": "Month01",
"transitions": [
{
"date": "01/01/2010",
"purchase": 120
},
{
"date": "01/01/2010",
"purchase": 120
},
{
"date": "01/01/2010",
"purchase": 120
}
]
},
{
"month": "Month02",
"transitions": [
{
"date": "01/01/2010",
"purchase": 120
},
{
"date": "01/01/2010",
"purchase": 120
},
{
"date": "01/01/2010",
"purchase": 120
}
]
}
]
},
{
"account": "ABC123",
"name": "JohnDoe",
"purchase_history": [
{
"month": "Month01",
"transitions": [
{
"date": "01/01/2010",
"purchase": 120
},
{
"date": "01/01/2010",
"purchase": 120
},
{
"date": "01/01/2010",
"purchase": 120
}
]
},
{
"month": "Month02",
"transitions": [
{
"date": "01/01/2010",
"purchase": 120
},
{
"date": "01/01/2010",
"purchase": 120
},
{
"date": "01/01/2010",
"purchase": 120
}
]
}
]
}
]
I can see that I was able to download the customer details in console.log("customerID", customerRewards); However, when I tried to access {customerRewards.name}, it won't display the name at all....
What am I missing? Could it have something to do with the params that I'm trying to link to? I tried to link by account instead of _id
Your piece of state, customerRewards is an array when it comes from the API. So even when you declare your initial state with an object {}, customerRewards is always going to be an array with one element in this case. Could be an issue in your API response - I'm not familiar with MongoDB Atlas or if it creates access patterns for you but you should be able to configure to return a singular object with a unique ID rather than an array of 1 element.
For now you could do:
this.setState({
customerRewards: res.data[0] /** could do res.data.shift() as well */
})
I would figure out why you are returning an array if there is only supposed to be one element coming back.
just select the element which name you want to get:
customerRewards[0].name

How do I grab this API data using ReactJS

Hi Could anyone help with this? I am trying to grab my API data from this API request but cannot seem to manage how to grab the bit I need.
Basically what I need to display in my <p></p> is this "astronomical": "0.4838725338",
Here is my json data
{
"links": {
"next": "https=DEMO_KEY",
},
"element_count": 6,
"near_objects": {
"2018-12-28": [
{
"links": {
"self": "x"
},
"id": "2450238",
"estimated_diameter": {
"kilometers": {
"estimated": 0.6089126221,
"estimatedmax": 1.3615700154
}
},
"is_potentially": false,
"approach": [
{
"date": "2018-12-28",
"epoch": 1545984000000,
"distance": {
"astronomical": "0.4838725338",
"lunar": "188.2264099121",
},
"orbitinody": "Nobes"
}
],
And here is my Component
class App extends Component {
state = {
data : []
}
componentDidMount() {
this.fetchasa();
}
fetchasa = () => {
fetch('https:?de_KEY')
.then((response) => response.json())
.then((result) => this.setState({
data: result.near_objects.2018-12-28.approach.distance[0]
}))
}
render() {
const {data} = this.state;
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>Edit <code>src/App.js</code> and save to reload.</p>
<p>astronomical: {data}</p>
</header>
</div>
);
}
}
export default App;
Please help and thank you in advance :D
Try with:
result.near_objects['2018-12-28'][0].approach[0].distance.astronomical
If you don't know the index names of near_objects prior to the request, you can get the date value like this
const [first] = Object.keys(result.near_objects)
result.near_objects[first][0].approach[0].distance.astronomical

Displaying data from json as suggestions under a searchbar in reactjs

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.

Import JSON data in to array in REACTJS

So ive been looking at this for a couple hours now trying to get my head around it but I just cant figure it out.
I have a json file located at '/src/data/topbar.json' which i want to include in my topbar-container component which will be used to generate the top menu.
What am I doing wrong here?
topbar.json:
{
"topbarLinks": [
{
"id": 1,
"icon": "header__topbar__list__link__icon glyphicon glyphicon-home",
"text": "home",
"link": "/"
},
{
"id": 2,
"icon": "header__topbar__list__link__icon glyphicon glyphicon-euro",
"text": "Pricing",
"link": "/pricing"
},
{
"id": 3,
"icon": "header__topbar__list__link__icon glyphicon glyphicon-exclamation-sign",
"text": "Help",
"link": "/help"
},
{
"id": 4,
"icon": "header__topbar__list__link__icon glyphicon glyphicon-question-sign",
"text": "FAQ",
"link": "/faq"
},
{
"id": 5,
"icon": "header__topbar__list__link__icon glyphicon glyphicon-edit",
"text": "Register",
"link": "/register"
},
{
"id": 6,
"icon": "header__topbar__list__link__icon glyphicon glyphicon-share",
"text": "Login",
"link": "/login"
}
]
}
topbar-container.js
import React, { Component } from 'react';
import './topbar-container.scss';
import Link from '../topbar-link/topbar-link';
require ('../../data/topbar.json');
class TopbarContainer extends Component {
constructor() {
super();
this.State = {
topbarLinks: []
}
}
componentDidMount() {
fetch('../../data/topbar.json')
.then(results => {
return results.json();
}).then(data => {
let topbarLinks = data.results.map((topbarLinks, key) => {
return (
<Link
key={topbarLinks.id}
text={topbarLinks.text}
icon={topbarLinks.icon}
link={topbarLinks.link}
/>
)
})
})
}
render() {
return (
<div className="container-fluid header__topbar">
<div className="row">
<div className="container">
<ul className="header__topbar__list">
{this.state.topbarLinks}
</ul>
</div>
</div>
</div>
);
}
}
export default TopbarContainer;
You can't fetch a local JSON file, you either have to import it, or setup a webserver that will serve that JSON file
import myJson from '../../data/topbar.json';
Then just map over it and don't forget to setState
componentDidMount() {
let topbarLinks = myJson.topbarLinks.map((topbarLinks, key) => {
return (
<Link
key={topbarLinks.id}
text={topbarLinks.text}
icon={topbarLinks.icon}
link={topbarLinks.link}
/>
)
})
this.setState({topbarLinks: topbarLinks}); // <--
//or just this.setState({ topbarLinks });
}
and as somebody else noted this.state has to be lowercase
topbar.json:
export default {
"topbarLinks": []
}
then you can simply import it without fetch
import data from '../../data/topbar.json'
let topbarLinks = data.results.map((topbarLinks, key) => {
return (
;
I don't think that State should be capitalized in this.State in your constructor.
Change map function to data.topbarLinks.map to access json data.
let topbarLinks = data.topbarLinks.map((topbarLinks, key) => {
return (
<Link
key={topbarLinks.id}
text={topbarLinks.text}
icon={topbarLinks.icon}
link={topbarLinks.link}
/>
)
})
And then set state
this.setState({topbarLinks: topbarLinks});
Change your initial state as this.State to this.state in constructor.