Showing only the good ones
Hide the shows you would not watch, and put a badge on the ones you would.
The watchlist draws every show in the array. A list is more useful when it leaves things out, and when each card says a little more about itself.
Hiding the shows you would not watch
There is a fourth show in the array below, and it is not very good. filter
gives you a new array with only the shows that pass a test, and you map that
instead of the full list. filter is
Array Methods: map, filter, reduce.
The line at the top reads 3 of 4 shows are worth watching, and there are three
cards. filter did not remove Emily in Paris from shows; it made a second
array without her. Raise 8 to 8.5 and a second card goes.
Show something, or nothing
Sometimes you want one part of a card, and only sometimes. There is no if
inside JSX, because braces hold an expression, not a statement. && does the
job: test && <span>...</span> gives you the element when test is true, and
nothing when it is false.
Nothing means false, null or undefined. React draws none of them.
The trap is what counts as false. These six values are falsy: false, 0,
"" (an empty string), null, undefined and NaN. Everything else is
truthy. && gives back the left value when that value is falsy — and 0 is a
value React can draw.
The first panel reads The Bear: 4 episodes left, then Andor: 0. Andor's
count is 0, so && hands back 0, and React draws that bare 0 where a
sentence should be. The second panel reads Andor: and stops, because 0 > 0
is false. Put a comparison on the left of &&, not a number.
The third panel shows the two fallbacks. || falls back on any falsy value, so
it turns Andor's real count of 0 into not started, which is wrong. ??
falls back only on null and undefined, so Andor keeps its 0 and Emily,
who has no count at all, gets the text.
Either one thing or the other
&& can only show a thing or show nothing. When you want one of two things,
use a ternary: test ? a : b. Both panels below have an empty watchlist.
The && panel is empty. An empty list is a normal thing to have, and a page
that says nothing about it looks broken. The ternary panel says
Nothing to watch yet.
A component can return nothing
A ternary is hard to read once the two sides are more than a line. When a
component has nothing to draw, it can return null instead, and the parent
uses it without a condition.
Row says <TopRatedBadge rating={rating} /> both times. The badge decides for
itself, and Andor's row simply has no badge. Returning undefined is not the
same: a component must return something, and null is that something.
The badge on the good ones
Now put it in the app. Each show gets an episodesLeft count: the number of
episodes you have not watched. Andor is finished, so its count is 0.
The card shows a Top rated badge above 8.5, in the same pill as the genre,
and a line of episodes left only when there are any. The count at the top uses a
ternary, so an empty list still says something.
Four shows in the array, three cards on the page. The Bear and Severance carry
the badge, Andor does not, and Andor has no episodes line because its count is
0.
Common mistakes
- A number on the left of
&&.{episodesLeft && ...}draws a bare0when the count is0; write{episodesLeft > 0 && ...}. ||for a fallback on a number. It replaces0as well asnull, so a real count of zero disappears;??only replacesnullandundefined.ifinside braces. Braces take an expression, so use a ternary, or anifabove thereturn.
Exercise
Two conditions on the cards are wrong. Andor's card shows a stray 0 where its
episodes line would be, and every card carries the Top rated badge, including
Andor at 8.4.
Fix both so the page reads:
3 of 4 shows are worth watching. Three cards: The Bear, badge, 4
episodes left. Severance, badge, 2 episodes left. Andor, no badge,
nothing under its year, and no stray 0 anywhere.
Hint: both conditions test a number. && gives back the left value when it is
falsy, and every rating here is truthy.