I'm trying to have something conditionally rendered based on the length of the array I receive from the backend which contain objects. If the length is 0, then I want it to say something like "no projects" and if the length is > 0 then I want it to just display the projects on the screen. Here is what I tried doing:
// Main component handling the filter body
class FilterBody extends React.Component {
constructor(props) {
super(props);
this.state = {
// Variables
projects: null,
assignment_type: "",
sdg: [""],
theme: [""],
keywords: [""],
orginization: "",
jsonLength: 1,
// Select module features
isClearable: true,
isSearchable: true,
};
this.handleSubmit = this.handleSubmit.bind(this);
}
// Handling all 3 input submissions
handleSubmit(event) {
event.preventDefault();
const data = {
sdg: this.state.sdg,
assignment_type: this.state.assignment_type,
orginization: this.state.orginization,
keywords: this.state.keywords
}
fetch(`/api/projects/filter?sdg=${encodeURIComponent(data.sdg)}&assignment_type=${encodeURIComponent(data.assignment_type)}&orginization=${encodeURIComponent(data.orginization)}&keywords=${encodeURIComponent(data.keywords)}`, {
method: "GET",
headers: {
'Content-Type': 'application/json;charset=utf-8',
},
})
.then(response => response.json())
.then(json => (this.setState({projects: json}), {jsonLength: json.length}))
.then(jsonLength => console.log(jsonLength)) // DEBUG
}
async componentDidMount() {
const response = await fetch('/api/projects')
const json = await response.json()
if (response.ok) {
this.setState({projects: json})
}
}
projectDisplay() {
return (
<>
<div className="content">
{this.state.projects && this.state.projects.map((project) => (
<ProjectDetails key={project._id} project={project}/>
))}
</div>
</>
)
}
render() {
return (
<>
<div className="filterHome">
<div className="filterContainer">
{/* Lists projects */}
<div className="projects">
// THIS IS WHAT I TRIED DOING THE FIRST TIME WHICH DOESN'T WORK
{/* {this.state.jsonLength > 0 &&
<div className="content">
{this.state.projects && this.state.projects.map((project) => (
<ProjectDetails key={project._id} project={project}/>
))}
</div>
}
{this.state.jsonLength === 0 &&
<div >
No Projects
</div>
} */}
// THIS IS WHAT I TRIED DOING THE SECOND TIME WHICH STILL DOESN'T WORK
{this.state.jsonLength > 0 ? this.projectDisplay() : console.log('no projects')}
</div>
</div>
</>
);
}
}
export default FilterBody
This is what I tried doing the first time once something comes from the backend but this didn't work and just displayed nothing when jsonLength === 0
:
{this.state.jsonLength > 0 &&
<div className="content">
{this.state.projects && this.state.projects.map((project) => (
<ProjectDetails key={project._id} project={project}/>
))}
</div>
}
{this.state.jsonLength === 0 &&
<div >
No Projects
</div>
}
This is what I tried doing the second time but this didn't work either and when the statement was false it still didn't show no projects
in the console despite what I put:
{this.state.jsonLength > 0 ? this.projectDisplay() : console.log('no projects')}
Does anyone know why my conditional rendering isn't working?
CodePudding user response:
setState accepts a single object as the 1st argument & the 2nd optional argument is a callback function. It should be
this.setState({projects: json, jsonLength: json.length})
In my opinion, you can omit jsonLength
& use this.state.projects.length
instead.