UPDATE I can access everything just fine in the return statement of render() function. F.e user.exercises[0].exercise.name outputs "squats". That's why it's even more confusing why I can't access it before return statement to create a function mapping the values to a table. UPDATE
I seem to have problems with accessing specific keys in React. The object that I try to read is requested from backend API from mongodb and outputted as JSON. I've already tried accessing it after mapping the object to an array through lodash, but the issue is the same. I am probably just reading the object wrong and specifying the wrong key, but I cannot see it. I have no problems console.logging the whole JSON or the top keys, f.e "name", or "age" by writing {user.name}, but anything with more depth and it crashes. Here's the JSON:
{
"_id": "592ab4523a4d39085fe4c1d9",
"nickname": "mmsmsy",
"name": "Mateusz",
"gender": "male",
"age": 26,
"exercises": [
{
"exercise": {
"name": "squats",
"records": []
}
},
{
"exercise": {
"name": "legpresses",
"records": []
}
},
{
"exercise": {
"name": "deadlifts",
"records": []
}
},
{
"exercise": {
"name": "benchpresses",
"records": []
}
},
{
"exercise": {
"name": "pullups",
"records": []
}
},
{
"exercise": {
"name": "shoulderpresses",
"records": []
}
},
{
"exercise": {
"name": "curls",
"records": []
}
}
]
}
And the React code:
import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import axios from 'axios';
import _ from 'lodash';
class UserDetails extends Component{
constructor(props) {
super(props)
this.state = {
user: null,
loading: false
}
}
componentDidMount() {
this.setState({
loading: true
});
axios.get(`http://192.168.0.248:3001/api/v1/users/${this.props.match.params.id}`)
.then(res => res.data)
.then(user => {
this.setState({
user: user,
loading: false
});
});
}
render() {
const {loading, user} = this.state;
let userInfo = _.map(user, (value, prop) => {
return { "prop": prop, "value": value };
});
console.log(user, userInfo);
if (loading || !user) {
return (
<p className="user-loading">Loading ...</p>
);
}
return (
<div id="user-details">
<div className="nav">
<Link className="nav-back-to-list" to="/">Back to the list</Link>
</div>
<div id="user-details-icon">
<img src={`/images/user_${user.gender}.png`} alt={`generic user ${user.gender} icon`} />
</div>
<table>
<tbody><tr><td>Nickname</td><td>{user.nickname}</td></tr></tbody>
<tbody><tr><td>Name</td><td>{user.name}</td></tr></tbody>
<tbody><tr><td>Gender</td><td>{user.gender}</td></tr></tbody>
<tbody><tr><td>Age</td><td>{user.age}</td></tr></tbody>
</table>
<h1>Records</h1>
</div>
)
}
}
export default UserDetails;
Here's what I get without error with console.log(user);
Object {_id: "592ab4523a4d39085fe4c1d9", nickname: "mmsmsy", name: "Mateusz", gender: "male", age: 26…}age: 26exercises: Array(7)0: Objectexercise: Objectname: "squats"records: Array(0)length: 0__proto__: Array(0)__proto__: Objectconstructor: function Object()hasOwnProperty: function hasOwnProperty()isPrototypeOf: function isPrototypeOf()propertyIsEnumerable: function propertyIsEnumerable()toLocaleString: function toLocaleString()toString: function toString()valueOf: function valueOf()__defineGetter__: function __defineGetter__()__defineSetter__: function __defineSetter__()__lookupGetter__: function __lookupGetter__()__lookupSetter__: function __lookupSetter__()get __proto__: function __proto__()set __proto__: function __proto__()__proto__: Object1: Objectexercise: Object__proto__: Object2: Object3: Object4: Object5: Object6: Objectlength: 7__proto__: Array(0)gender: "male"name: "Mateusz"nickname: "mmsmsy"_id: "592ab4523a4d39085fe4c1d9"__proto__: Object
and here's after converting it with lodash to an array console.log(userInfo);
(6) [Object, Object, Object, Object, Object, Object]
Now, the example and the error that I get if I try to access f.e: console.log(user.exercises[0].exercise.name);
Uncaught TypeError: Cannot read property 'exercises' of null
at UserDetails.render (UserDetails.js:33)
at ReactCompositeComponent.js:796
at measureLifeCyclePerf (ReactCompositeComponent.js:75)
at ReactCompositeComponentWrapper._renderValidatedComponentWithoutOwnerOrContext (ReactCompositeComponent.js:795)
at ReactCompositeComponentWrapper._renderValidatedComponent (ReactCompositeComponent.js:822)
at ReactCompositeComponentWrapper.performInitialMount (ReactCompositeComponent.js:362)
at ReactCompositeComponentWrapper.mountComponent (ReactCompositeComponent.js:258)
at Object.mountComponent (ReactReconciler.js:46)
at ReactCompositeComponentWrapper.performInitialMount (ReactCompositeComponent.js:371)
at ReactCompositeComponentWrapper.mountComponent (ReactCompositeComponent.js:258)
at Object.mountComponent (ReactReconciler.js:46)
at ReactDOMComponent.mountChildren (ReactMultiChild.js:238)
at ReactDOMComponent._createInitialChildren (ReactDOMComponent.js:697)
at ReactDOMComponent.mountComponent (ReactDOMComponent.js:516)
at Object.mountComponent (ReactReconciler.js:46)
at ReactCompositeComponentWrapper.performInitialMount (ReactCompositeComponent.js:371)
at ReactCompositeComponentWrapper.mountComponent (ReactCompositeComponent.js:258)
at Object.mountComponent (ReactReconciler.js:46)
at ReactCompositeComponentWrapper.performInitialMount (ReactCompositeComponent.js:371)
at ReactCompositeComponentWrapper.mountComponent (ReactCompositeComponent.js:258)
at Object.mountComponent (ReactReconciler.js:46)
at ReactCompositeComponentWrapper.performInitialMount (ReactCompositeComponent.js:371)
at ReactCompositeComponentWrapper.mountComponent (ReactCompositeComponent.js:258)
at Object.mountComponent (ReactReconciler.js:46)
at mountComponentIntoNode (ReactMount.js:104)
at ReactReconcileTransaction.perform (Transaction.js:140)
at batchedMountComponentIntoNode (ReactMount.js:126)
at ReactDefaultBatchingStrategyTransaction.perform (Transaction.js:140)
at Object.batchedUpdates (ReactDefaultBatchingStrategy.js:62)
at Object.batchedUpdates (ReactUpdates.js:97)
at Object._renderNewRootComponent (ReactMount.js:320)
at Object._renderSubtreeIntoContainer (ReactMount.js:401)
at Object.render (ReactMount.js:422)
at Object.<anonymous> (index.js:10)
at __webpack_require__ (bootstrap 9a6d4f1…:657)
at fn (bootstrap 9a6d4f1…:85)
at Object.<anonymous> (fetch.js:461)
at __webpack_require__ (bootstrap 9a6d4f1…:657)
at validateFormat (bootstrap 9a6d4f1…:706)
at bundle.js:710
render @ UserDetails.js:33
(anonymous) @ ReactCompositeComponent.js:796
measureLifeCyclePerf @ ReactCompositeComponent.js:75
_renderValidatedComponentWithoutOwnerOrContext @ ReactCompositeComponent.js:795
_renderValidatedComponent @ ReactCompositeComponent.js:822
performInitialMount @ ReactCompositeComponent.js:362
mountComponent @ ReactCompositeComponent.js:258
mountComponent @ ReactReconciler.js:46
performInitialMount @ ReactCompositeComponent.js:371
mountComponent @ ReactCompositeComponent.js:258
mountComponent @ ReactReconciler.js:46
mountChildren @ ReactMultiChild.js:238
_createInitialChildren @ ReactDOMComponent.js:697
mountComponent @ ReactDOMComponent.js:516
mountComponent @ ReactReconciler.js:46
performInitialMount @ ReactCompositeComponent.js:371
mountComponent @ ReactCompositeComponent.js:258
mountComponent @ ReactReconciler.js:46
performInitialMount @ ReactCompositeComponent.js:371
mountComponent @ ReactCompositeComponent.js:258
mountComponent @ ReactReconciler.js:46
performInitialMount @ ReactCompositeComponent.js:371
mountComponent @ ReactCompositeComponent.js:258
mountComponent @ ReactReconciler.js:46
mountComponentIntoNode @ ReactMount.js:104
perform @ Transaction.js:140
batchedMountComponentIntoNode @ ReactMount.js:126
perform @ Transaction.js:140
batchedUpdates @ ReactDefaultBatchingStrategy.js:62
batchedUpdates @ ReactUpdates.js:97
_renderNewRootComponent @ ReactMount.js:320
_renderSubtreeIntoContainer @ ReactMount.js:401
render @ ReactMount.js:422
(anonymous) @ index.js:10
__webpack_require__ @ bootstrap 9a6d4f1…:657
fn @ bootstrap 9a6d4f1…:85
(anonymous) @ fetch.js:461
__webpack_require__ @ bootstrap 9a6d4f1…:657
validateFormat @ bootstrap 9a6d4f1…:706
(anonymous) @ bundle.js:710