Reputation: 197
This is codesandbox I want to ask about -> https://codesandbox.io/s/2pwx46572n
When I click 'Add module' button it says 'Cannot read property 'id' of null'. I believe the problem is in thematicArea.jsx component (components -> singleModuleComponent -> thematicArea.jsx) in line 42 (key={f.id}). It says it's null after 'Add module' click, but when I console.log it in line 32 it doesn't seem to be null. So...what the problem might be? Can anybody help me to fix this?
Below thematicArea.jsx code:
import React, { Component } from "react";
import SingleModule from "./singleModule";
import { Row } from "react-bootstrap";
import _ from "lodash";
class ThematicArea extends Component {
constructor(props) {
super(props);
this.takeModuleNameFromSingleModule = this.takeModuleNameFromSingleModule.bind(
this
);
}
takeModuleNameFromSingleModule(value) {
this.props.moveModuleNameUpToApp(value);
}
orderedModules = _.groupBy(this.props.modules, thematicArea => {
return thematicArea.thematicArea;
});
render() {
console.log(this.orderedModules);
console.log(this.props);
return (
<Row>
<div>
{
(this.orderedModules = Object.keys(this.orderedModules).map(e => {
return (
<div key={e}>
<h3 key={e}>{e}</h3>
{/*console.log(
Object.values(this.orderedModules[e]).map(f => f.name + f.id)
)*/}
{Object.values(this.orderedModules[e]).map(f => (
<SingleModule
moveModuleNameUpToThematicArea={
this.takeModuleNameFromSingleModule
}
clickedModuleNames={this.props.clickedModuleNames}
chosenModulesNames={this.props.chosenModulesNames}
key={f.id}
{...f}
/>
))}
</div>
);
}))
}
</div>
</Row>
);
}
}
export default ThematicArea;
singleModule.jsx (here module is displayed)
import React, { Component } from "react";
import ShowModuleDetails from "./showModuleDetails";
import AddModule from "./addModule";
import { Col } from "react-bootstrap";
class SingleModule extends Component {
constructor(props) {
super(props);
this.takeModuleNameFromAddModule = this.takeModuleNameFromAddModule.bind(
this
);
}
takeModuleNameFromAddModule(value) {
this.props.moveModuleNameUpToThematicArea(value);
}
render() {
return (
<Col
xs={12}
md={6}
lg={3}
className={
this.props.chosenModulesNames.includes(this.props.name) === true
? /*"single-module col-12 col-md-6 col-lg-3 col-xl-2*/ "single-module single-module--added"
: /*'single-module col-12 col-md-6 col-lg-3 col-xl-2*/ "single-module single-module--not-added"
}
>
<h4 className="sindgle-module__thematic-area-display">
{this.props.thematicArea}
</h4>
<h3 className="single-module__module-name-display">
{this.props.name}
</h3>
<div className="single-module__buttons">
<ShowModuleDetails
details={this.props.details}
name={this.props.name}
/>
<AddModule
moveModuleNameUpToSingleModule={this.takeModuleNameFromAddModule}
isAdded={this.isAdded}
addNewModuleToList={this.handleAddNewModuleToList}
name={this.props.name}
clickedModuleNames={this.props.clickedModuleNames}
chosenModulesNames={this.props.chosenModulesNames}
/>
</div>
</Col>
);
}
}
export default SingleModule;
And addModule.jsx (shows what happens after adding a module)
import React, { Component } from "react";
import { Button } from "react-bootstrap";
class AddModule extends Component {
constructor(props) {
super(props);
this.handleAddModuleToList = this.handleAddModuleToList.bind(this);
}
handleAddModuleToList() {
this.props.moveModuleNameUpToSingleModule(this.props.name);
}
isButtonDisabled = (chosenModulesNames, name) =>
chosenModulesNames.includes(name);
render() {
const { chosenModulesNames, name } = this.props;
return (
<div>
<Button
disabled={
this.props.chosenModulesNames.length === 122
? true
: this.isButtonDisabled(chosenModulesNames, name)
}
bsStyle="primary"
onClick={this.handleAddModuleToList}
className={
this.isButtonDisabled(chosenModulesNames, name) === true
? "single-module__buttons--chosen"
: "single-module__buttons--not-chosen"
}
>
{this.isButtonDisabled(chosenModulesNames, name) === true
? "Dodano!"
: "Dodaj moduł"}
</Button>
</div>
);
}
}
export default AddModule;
Upvotes: 0
Views: 5438
Reputation: 85545
Verify this.orderedModules
has data when it's being rendered like:
this.orderedModules && Object.keys(this.orderedModules).map(e => {
If everything works just fine in your current code, then you may also use:
key={f && f.id}
Upvotes: 1