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?
Advertisement
Answer
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.