ReactJS- can't read JSON array - json

My App.jsx file is below.
import React from 'react';
class App extends React.Component {
constructor() {
super();
this.state = {
data:require('json!./dataa.json')
}
}
render() {
return (
<body>
<div>
<Header/>
<center>
<table>
<tr><th>NAME</th><th>VALUE</th><th>COLOR</th><th>Edit Table</th></tr>
<tbody>
{this.state.data.table.map(person, i) => <TableRow key = {i} data = {person} />)}
</tbody></table></center>
</div>
</body>
);
}
}
class Header extends React.Component {
render() {
return (
<div><center>
<h1>Creation of table from JSON</h1></center>
</div>
);
}
}
class TableRow extends React.Component {
render() {
return (
<tr>
<td>{this.props.data.NAME}</td>
<td>{this.props.data.VALUE}</td>
<td>{this.props.data.COLOR}</td>
<td contentEditable='true'></td>
</tr>
);
}
}
export default App;
and my dataa.json file is like below
[{"table":
[{"NAME":"Alan","VALUE":12,"COLOR":"blue"},
{"NAME":"Shan","VALUE":13,"COLOR":"green"},
{"NAME":"John","VALUE":45,"COLOR":"orange"},
{"NAME":"Minna","VALUE":27,"COLOR":"teal"}]
}]
Question: It is compiled fine. but it display error in browser "cannot read the property of map undefined".How to resolve
Note: but it works fine when the json file like,
[{"NAME":"Alan","VALUE":12,"COLOR":"blue"},
{"NAME":"Shan","VALUE":13,"COLOR":"green"},
{"NAME":"John","VALUE":45,"COLOR":"orange"},
{"NAME":"Minna","VALUE":27,"COLOR":"teal"}]
}]

this.state.data doesn't have property table, because it is an array of single object.
Correct JSON structure to this
{
"table": [
{"NAME":"Alan","VALUE":12,"COLOR":"blue"},
{"NAME":"Shan","VALUE":13,"COLOR":"green"},
{"NAME":"John","VALUE":45,"COLOR":"orange"},
{"NAME":"Minna","VALUE":27,"COLOR":"teal"}
]
}
and use this.state.data.table.map.

Related

How to pass json data object {items.symbol} value to another class

I am using React js. I have a class Stock.js where I am fetching an api and displaying the data on the webpage in the form of table.
When I click on the table data (table data are links) It sends the item.symbol to onhandleclick() method. For example:
|Symbol|Age|
|X | 20|
|Y |22 |
So the values in symbol table are referred as item.symbol
Here if I click on X it sends the value X to onhandleclick() and now I want to send this value X or Y whichever user clicks on to another class. By another class I mean let's say I have a class xyz.js I wanna send the value of item.symbol to class xyz.js so I can use this value and do whatever I want with that value in my xyz.js class. Is there a way to do it?
My code: (Stock.js)
import React, { Component } from "react";
import { Link } from "react-router-dom";
import Symbols from "./Symbols";
export default class Stocks extends Component {
constructor(props) {
super(props);
this.state = {
items: [],
isLoaded: false,
symbolsname: "",
};
}
handleClick(symbol) {
//pass the value to another class here
}
componentDidMount(symbol) {
fetch("http://131.181.190.87:3001/all")
.then((res) => res.json())
.then((json) => {
this.setState({
isLoaded: true,
items: json,
});
});
}
render() {
let filteredItems = this.state.items.filter((item) => {
return (
item.symbol.toUpperCase().indexOf(this.state.search.toUpperCase()) !==
-1 || item.industry.indexOf(this.state.search) !== -1
);
});
var { isLoaded, items } = this.state;
if (!isLoaded) {
return <div>Loading...</div>;
} else {
return (
<div>
<table border={2} cellPadding={1}>
<thead>
<tr>
<th>Symbol</th>
<th>Name</th>
<th>Industry</th>
</tr>
</thead>
<tbody>
{filteredItems.map((item) => (
<tr>
<Link to="/symbols">
<td
key={item.symbol}
onClick={() => this.onhandleclick(item.symbol)} //here I am passing the value of item.symbol to onhandleclick()
>
{item.symbol}
</td>
</Link>
<td key={item.name}>{item.name}</td>
<td key={item.industry}>{item.industry}</td>
</tr>
))}
}
</tbody>
</table>
</div>
);
}
}
}
After doing what maniraj-murugansaid in the answers, it says undefined, so I have uploaded the screenshot
You could redirect to symbol.js using history.push with click event handler like, (Remove Link tag here) So change,
<Link to="/symbols">
<td key={item.symbol} onClick={() => this.onhandleclick(item.symbol)} //here I am passing the value of item.symbol to onhandleclick()>
{item.symbol}
</td>
</Link>
to,
<td key={0} onClick={() => this.onhandleclick(item.symbol)}
style={{ cursor: "pointer", color: "blue" }}
>
{item.symbol}
</td>
And onHandleClick function like,
onhandleclick(data) {
const { history } = this.props;
history.push({
pathname: "/Symbol",
symbol: data
});
}
Here the second property is props that you can pass which is symbol in your case so you can give it like, symbol: data ..
Working Sandbox: https://codesandbox.io/s/react-router-v4-withrouter-demo-2luvr
Update:
-> After the update from OP , there are some changes that have been made.
=> import { BrowserRouter } from "react-router-dom"; in the main component index.js where you are initializing the parent component in the call to ReactDOM.render .
index.js:
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import { BrowserRouter } from "react-router-dom";
const rootElement = document.getElementById("root");
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>,
rootElement
);
stocks.js:
import React, { Component } from "react";
import { Link } from "react-router-dom";
import Symbols from "./Symbols";
const filteredItems = [
{ symbol: "X", name: "item1", industry: "industry1" },
{ symbol: "Y", name: "item2", industry: "industry2" }
];
export default class Stocks extends Component {
constructor(props) {
super(props);
this.state = {
items: [],
isLoaded: false,
search: "",
symbol: ""
};
}
updateSearch(event) {
this.setState({ search: event.target.value });
}
onhandleclick(data) {
const { history } = this.props;
history.push({
pathname: "/Symbols",
symbol: data
});
}
componentDidMount() {}
render() {
return (
<div>
<form className="form-for-table-search">
Search symbol or industry:  
<input
type="text"
value={this.state.search}
onChange={this.updateSearch.bind(this)}
/>
   {" "}
<button type="button" className="btn-submit">
Search
</button>
<br />
</form>
<table border={2} cellPadding={1}>
<thead>
<tr>
<th>Symbol</th>
<th>Name</th>
<th>Industry</th>
</tr>
</thead>
<tbody>
{filteredItems.map((item, index) => (
<tr key={index}>
<td
key={0}
onClick={() => this.onhandleclick(item.symbol)} //here I am passing the value of item.symbol to onhandleclick()
style={{ cursor: "pointer", color: "blue" }}
>
{item.symbol}
</td>
<td key={item.name}>{item.name}</td>
<td key={item.industry}>{item.industry}</td>
</tr>
))}
</tbody>
</table>
</div>
);
}
}
Symbols.js:
import React from "react";
export default class Symbol extends React.Component {
componentDidMount() {
console.log("came here", this.props.location.symbol);
}
render() {
return <div>Symbol value: {this.props.location.symbol}</div>;
}
}
Updated Sandbox
You could export a function from Symbol.js and use that in handleClick.
// Symbol.js
export default class Symbol {
doSomething(symbol) {
// do something
}
}
// Stocks.js
import Symbol from 'Symbol.js';
handleClick(symbol) {
Symbol.doSomething(symbol);
};

fetching json data from local file

TypeError: this.state.data.map is not a function
Trying to access local json data.
import React, { Component } from 'react';
import './index.css'
class App extends Component {
constructor(){
super()
this.state = {
data: []
}
}
componentDidMount()
{
fetch("./employeeData.json")
.then(res => res.json())
.then(daabta => {
this.setState({data: daabta })
} )
}
render() {
return (
<table>
<tbody>{this.state.data.map((item, index) =>
<tr key = {index}>
<td>{item.userId}</td>
<td>{item.firstName}</td>
<td>{item.lastName}</td>
<td>{item.region}</td>
</tr>
)
})}</tbody>
</table>
)
}
}
export default App;
You can just import your json file directly at the top of your component like
import * as employeeData from "./employeeData.json";
but be careful your json data would be inside and object named default so when you want to access the data you should use employeeData.default

How to render image from JSON string into my react application?

This is my JSON string:
{"blocks":
[{
"key":"mm3r",
"text":"",
"type":"unstyled",
"depth":0,
"inlineStyleRanges":[],
"entityRanges":[],
"data":{}}],
"entityMap":
{
"0":
{
"type":"IMAGE",
"mutability":"MUTABLE",
"data":{"src":"https://t00.deviantart.net/1vvQLZ9mzHkH16x62-aLZmIlY1I=/fit-in/300x900/filters:no_upscale():origin()/pre00/e334/th/pre/f/2014/270/7/e/protect__luffy_x_suicidal_reader__by_wulferious-d80s516.png",
"height":"auto",
"width":"auto"
}
}
}
}
Following is my react component:
let theObject;
class Blog extends Component{
constructor(props){
super(props);
this.blogContent = props.blogContent;
this.blogId = props.blogId;
}
This is where I'm doing JSON.parse
componentWillMount(){
theObject = JSON.parse( this.blogContent );
console.log(this.blogContent);
}
Here is my render part. Presently I'm just calling theObject.blocks[i].text which works fine but I don't know how to render the image. In short how should I call it??
render(props) {
return(
<div className = "blog header">
{
Array.from(Array(theObject.blocks.length), (e, i) => {
return <p key={i}>{theObject.blocks[i].text }</p>
})}
</div>
);
}
}
Blog.proptypes = {
blogContent: Proptypes.string
}
export default Blog;
Seems like you would need to iterate over the entityMap values and use the data.src for each of them for the image source.
Something along these lines:
Object.values(theObject.blocks[i].entityMap).map(val => <img src={val.data.src} />)

Syntax error: Unexpected token m in JSON at position 0 in React App

I am new to ReactJS,now working on small project. I am trying to load data from a JSON file,but I'm getting this "Syntax error: Unexpected token m in JSON at position 0 at JSON.parse ()". Thanks in advance.
Here is my code :
import React from 'react';
import dataa from './src/dataa.json';
class App extends React.Component {
constructor() {
super();
this.state = {
data:require('json!./dataa.json')
}
}
render() {
return (
<div>
<Header/>
<table>
<tbody>
{this.state.data.map((person, i) => <TableRow key={i} data={person} />)}
</tbody>
</table>
</div>
);
}
}
class TableRow extends React.Component {
render() {
return (
<tr>
<td>{this.props.data.id}</td>
<td>{this.props.data.name}</td>
<td>{this.props.data.age}</td>
</tr>
);
}
}
export default App;
and JSON data:
[{"id":"1","name":"Smith","age":"20"},
{"id":"2","name":"Jackson","age":"94"},
{"id":"3","name":"Doe","age":"80"},
{"id":"4","name":"Johnson","age":"37"}]

this.state.post.map is not a function

I am receiving json data from server and i am trying to access it individually using map function in front end but i am receiving an error as this.state.post.map is not a function. below is the code how do i overcome this.
import React from 'react';
import axios from 'axios';
//require('./style.scss');
class Premontessori extends React.Component{
constructor(props){
super(props);
this.state={
post:[]
};
}
componentDidMount(){
let self = this;
axios.get('http://localhost:8080/list')
.then(function(data) {
console.log(data);
self.setState({post:data});
});
}
render(){
return (
<div>
<table>
<tbody>
{
this.state.post.map(function(item, index){
return (
<tr>
<td>{item.Id}</td>
<td>{item.Name}</td>
<td>{item.Age}</td>
</tr>
)
})
}
</tbody>
</table>
</div>
);
}
}
export default Premontessori;
From your comment,
'since this.state.post is not an array hence you get an error that map is not a function.
You need to map over the data in the post object like
<tbody>
{this.state.post.data.map(function(item, index) {
return (
<tr key={index}>
<td>{item.Id}</td>
<td>{item.Name}</td>
<td>{item.Age}</td>
</tr>
)
})
}
</tbody>
I think you have to make an adjustment in the code in the componentDidMount life-cycle method as shown below. This is because the response from the axios call is wrapping the array data, so you have to fetch that array and update your state if the status code is 200.
import React from 'react';
import axios from 'axios';
//require('./style.scss');
class Premontessori extends React.Component{
constructor(props){
super(props);
this.state={
post:[]
};
}
componentDidMount(){
let self = this;
axios.get('http://localhost:8080/list')
.then(function(res) {
console.log(res);
if(res.status === 200){
self.setState({post:res.data});
}
})
.catch(function(err){
console.log(err);
});
}
render(){
return (
<div>
<table>
<tbody>
{
this.state.post.map(function(item, index){
return (
<tr>
<td>{item.Id}</td>
<td>{item.Name}</td>
<td>{item.Age}</td>
</tr>
)
})
}
</tbody>
</table>
</div>
);
}
}
export default Premontessori;