1

I'm trying to figure out conditional rendering in React. If there are no movies in the user's watchlist, i just want to output a title. I thought somethin like this would work:

render() {
    return (
        <Container>
            {this.state.watchlist.map(item => {
                if(this.state.watchlist.length > 0) {
                    return (
                        <WatchlistMovie
                            className="watchlist-movie"
                            key={item.id}
                            id={item.id}
                            title={item.title}
                            poster={item.poster}
                            overview={item.overview}
                            rating={item.rating}
                            user={this.props.user}
                        />
                    );
                } else {
                    return <h1>no movies</h1>
                }
            )}}
        </Container>
    );
}
5
  • Is this not working? Are you getting errors? Commented Mar 20, 2019 at 14:39
  • 1
    I believe you want the if-else logic outsides of the map Commented Mar 20, 2019 at 14:39
  • @Vencovsky No errors, just dont get the <h1> tag displayed if there are no movies in the watchlist Commented Mar 20, 2019 at 14:42
  • What is the <Container /> in your application? Is it set up to display this.props.children? Commented Mar 20, 2019 at 15:25
  • <Container> is a component from react-bootstrap <Container/> read more about it here: react-bootstrap.github.io Commented Mar 20, 2019 at 15:36

4 Answers 4

5

I believe you want the if-else logic outsides of the map

  <Container>
    {this.state.watchlist.length === 0 && <h1>no movies</h1>}

    {this.state.watchlist.map(item => (<WatchlistMovie
      className="watchlist-movie"
      key={item.id}
      id={item.id}
      title={item.title}
      poster={item.poster}
      overview={item.overview}
      rating={item.rating}
      user={this.props.user}
    />))}

  </Container>
Sign up to request clarification or add additional context in comments.

3 Comments

i get the logic of your answer, but it still seems not to be working for me, and i get no errors. If i check the React Dev tools, i can see the <h1> tag, however its greyed out.
@juicyj Then the problem is somewhere else. Because the second operand of && would only be executed if the first it truthy (which is of course not in case of an empty array)
got it, seems like bootstrap was being weird and hiding my element, thanks again Yury!
2

There's a problem in your code, which is that you check this.state.watchlist.length > 0 inside this.state.watchlist.map, and that you want to display the h1 element when the length is equal to 0.
The problem is that map() function iterates over all the elements of an array, and, if the array is empty, no callback is executed.

Thus, in your case, when this.state.watchlist.length is equal to 0, you don't even enter the map() function, so you can't render the h1 element at all.

As many user suggested, you should change your render method:

render() {
    const movieCounter = this.state.watchlist.length;
    return (
        <Container>
            {movieCounter === 0
                ? <h1>no movies</h1>
                : this.state.watchlist.map(item =>
                    <WatchlistMovie
                        className="watchlist-movie"
                        key={item.id}
                        id={item.id}
                        title={item.title}
                        poster={item.poster}
                        overview={item.overview}
                        rating={item.rating}
                        user={this.props.user}
                    />
                )}
            }
        </Container>
    );
}

In this example, what is happening is that you check if movieCounter is equal to 0: in that case, you display the h1 element, otherwise you iterate over all the films and display a WatchlistMovie Component for each one of them.

4 Comments

i get this logic as well, however just like with Yurys answer it seems to not be working for me either, and i get no errors. If i check the React Dev tools, i can see the <h1> tag, however its greyed out.
Can you explain me better what you mean with "greyed out"? Anyways, can you also post the Container implementation?
You're welcome. Though, try to explain what was the problem: some other users may end up in this question and need your answer too :)
My issue was that React-Bootstrap was hiding my element off the page for some reason, i just had to add margin top so the title was visible on my webpage. Both your code and Yury's worked flawlessly! thanks again :D
1

You can use what we call short circuit evaluation for conditional rendering in React.

render() {
return (
  <Container>

    {this.state.watchlist.length > 0 && (this.state.watchlist.map(item => {
      <WatchlistMovie
        className="watchlist-movie"
        key={item.id}
        id={item.id}
        title={item.title}
        poster={item.poster}
        overview={item.overview}
        rating={item.rating}
        user={this.props.user}
      />)}
    {this.state.watchlist.length === 0 && (
       <h1>no movies</h1>)
     }
  </Container>

);
}
}

In this type of expression if the first condition is true then the component will after it will be rendered otherwise it will be ignored

Comments

0

There is alot of ways to do this, this example shows how to do it using ternary. I think this is a better looking and smallert code, but you can also use Yury Tarabanko answer that do the same

render() {
    return (
      <Container>
        {this.state.watchlist.length > 0 ?
            this.state.watchlist.map(item => 
                <WatchlistMovie
                    className="watchlist-movie"
                    key={item.id}
                    id={item.id}
                    title={item.title}
                    poster={item.poster}
                    overview={item.overview}
                    rating={item.rating}
                    user={this.props.user}
                />
            })
            :
            <h1>no movies</h1>            
        }
      </Container>

    );
  }
}

1 Comment

Thanks for your quick response!

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.