0

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?

5
  • I don't think console.log('no projects') is an expression. Try with 'no projects` instead. Commented Aug 24, 2022 at 13:46
  • Are you getting errors? Plain objects (that is, objects that are not arrays) don't (necessarily) have a .length property. Commented Aug 24, 2022 at 13:46
  • @Pointy sorry, I am returned with an array which contain objects which is why I don't get an error. Commented Aug 24, 2022 at 13:47
  • @NiceBooks nothing appears even when I do that Commented Aug 24, 2022 at 13:48
  • What sets the .jsonLength value? I don't see anything that does that. Commented Aug 24, 2022 at 13:50

1 Answer 1

2

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.