this.state.post.map is not a function - json

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;

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

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"}]

ReactJS- can't read JSON array

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.

json not render with reactjs and redux

i load a .json with axios, and the file load well, but when i rendered dont work
editprofile.js --> create the dispatch, and load de json
export const editProfile = (callback)=>{
return function(dispatch){
dispatch({type: 'EDIT_PROFILE_REQUEST'});
axios({
method: 'get',
url: 'https://gist.githubusercontent.com/anonymous/38c1444f753c70cf79ee980638a14de7/raw/34951eebfa006fea3db00fb492b491ac990c788e/vamos.json',
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
})
.then((response)=>{
dispatch({type:'EDIT_PROFILE_SUCCESS', payload:response.data});
if (typeof callback === 'function') {
callback(null, response.data);
}
})
.catch((error) =>{
dispatch({type:'EDIT_PROFILE_FAILURE'});
if(error.response.status == 401){
browserHistory.push('login')
toastr.error(error.response.message, 'User')
}
if(typeof callback ==='function'){
callback(error.response.data, null)
}
})
}
}
EditProfileComponent.jsx -->created the component
export default class EditProfileComponent extends Component{
render(){
return(
<table>
<thead>
<tr>
<th>SN</th>
<th>Email</th>
<th>created</th>
</tr>
</thead>
<tbody>
{this.renderEditProfile()}
</tbody>
</table>
)
}
renderEditProfile(){
let sN = 1;
return this.props.allProfile.map((user)=>{
return(
<tr key={user.sN} >
<td>{sN++}</td>
<td>{user.email ? user.email : '---'}</td>
<td>{user.created_at ? user.created_at : '---'}</td>
</tr>
);
});
}
}
join the component with the service
import {editProfile} from '../action/editProfile.js';
import EditProfileComponent from '../component/editProfileComponent.jsx';
export default class EditProfileContainer extends Component{
componentDidMount(){
this.props.editProfile();
}
render (){
return (
<EditProfileComponent allProfile={this.props.allProfile} />
);
}
}
function mapStateToProps(store) {
return {
allProfile:store.allProfile
};
}
function matchDispatchToProps(dispatch){
return bindActionCreators({
editProfile:editProfile
}, dispatch)
}
export default connect
(mapStateToProps, matchDispatchToProps)(EditProfileContainer);
editProfileReducer --> the reducer
export const editProfileReducer = (state=[], action) =>{
switch(action.type){
case 'EDIT_PROFILE_REQUEST':
return state;
case 'EDIT_PROFILE_FAILURE':
return state;
case 'EDIT_PROFILE_SUCCESS':
return [...action.payload];
default:
return state;
}
}
join all the reducer
import { editProfileReducer } from './reducer/editProfileReducer.js'
const reducers = combineReducers({
allProfile:editProfileReducer,
});
export default reducers;
There is an error in your reducer. For EDIT_PROFILE_SUCCESS, it should be
case 'EDIT_PROFILE_SUCCESS':
return [...state, action.payload];
On a side note, you can take advantage of es6's arrow function:
export const editProfile = (callback) => (dispatch) => {
dispatch({type: 'EDIT_PROFILE_REQUEST'});
// ....
};
You also should use constants for action names.
I think there is problem with :
function mapStateToProps(store) {
return {
allProfile:store.allProfile
};
}
it should be:
function mapStateToProps(state) {
return {
allProfile:state.allProfile
};
}