
No Comments Yet
Be the first to share your thoughts and start the conversation.
Be the first to share your thoughts and start the conversation.
By logging in, you'll unlock full access to this and other free tutorials on JSM Pro.
Why? Logging in lets us personalize your learning experience, track your progress, and keep you in the loop with new workshops, coding tips, and platform updates.
You'll also be the first to know about upcoming launches, events, and exclusive discounts.
No spam—just helpful content to level up your skills.
If that sounds fair, go ahead and log in to continue →
Enter your name and email to get instant access
00:00:02 But just before I show you how to tweak that little homepage optimization, I want to make sure that we focus on the movie details page.
00:00:10 We've been staring at the search results and the homepage for such a long time, even the trending movies right now, but we were never able to fetch and
00:00:19 show all the movie details.
00:00:20 So let's do that next.
00:00:22 First, we have to create a function to gather all the movie information.
00:00:26 So head over into Services, API.ts.
00:00:32 And right below fetch movies, we want to create a new function, export const fetch movie details.
00:00:41 It'll be equal to an asynchronous function that simply accepts a movie ID of a type string, which will return a promise that'll ultimately resolve into
00:00:53 movie details.
00:00:53 And now we can open up the function block.
00:00:56 I'll open up a try and catch block.
00:00:59 In the catch, you know the drill.
00:01:01 If there is an error, simply console log that error and throw it, just so we can catch it somewhere else.
00:01:08 And in the try, we can make a fetch request similar to the one we made above, but this time to a different endpoint.
00:01:15 So let's say const response is equal to await fetch.
00:01:21 And now we can form the URL by first getting to the TMDB config dot base URL.
00:01:30 forward slash movie forward slash movie id question mark api underscore key is equal to tmdb config dot api key so we have just crafted the endpoint which
00:01:45 we want to call as the second parameter we want to provide it an object where the method will be set to get and the headers will be set to tmdbconfig.headers.
00:01:58 We already prepped everything beforehand.
00:02:01 Finally, if the response is not okay, we simply want to throw a new error.
00:02:09 Saying something like failed to fetch movies or movie details.
00:02:15 That's a bit more precise, but if response is okay, we want to get the data by awaiting the response.json.
00:02:24 Typically when you use fetch, you need to say response.json to extract the data.
00:02:29 And finally, we want to return the data, which in this case is the movie details.
00:02:35 So now that we have created this function, let's head over into the page that we haven't touched so far, which is this one.
00:02:42 Movies ID, a dynamic route that displays the details of that specific movie.
00:02:49 Let's start with the JSX.
00:02:51 We're wrapping everything with a view that has a class name equal to bg-primary and flex-1.
00:02:59 If I save it, how do we get to that page?
00:03:02 Well, you just have to click on one of the touchable opacities or one of the buttons.
00:03:08 So choose whichever one you want.
00:03:10 I'll go with the gladiator.
00:03:12 And now we can render the movie details.
00:03:14 I'll render them within a scroll view because it is possible that the height of the details will span more than the height of the device,
00:03:22 and I'll give it a content container style equal to padding bottom of 80. Within it, I'll display a view, and within that view,
00:03:33 I'll display an image that'll have a source equal to URI, And we once again have to have that starting part of a photo, https://image.tmdb.org forward
00:03:50 slash t forward slash w 500. And then we rendered the movie question mark dot poster path.
00:03:58 But of course, we first have to fetch the movie details.
00:04:01 So this is exactly where that function that we just created comes into the picture.
00:04:05 First, we need to get the ID of the movie that we're trying to get the details for.
00:04:10 And we can do that by destructuring the ID by using the use local search params hook.
00:04:17 Once we have the ID, it is pretty simple.
00:04:20 We just say const, destructure the data, rename it as movie.
00:04:27 also accept the loading and make it equal to the use fetch hook call within which we can have a callback function that then calls the fetch movie details.
00:04:39 And we need to pass the ID as a string right into it.
00:04:44 So now we get access to that movie.
00:04:46 And if you click on one of those movies.
00:04:51 You can see that we get redirected.
00:04:53 We no longer have an error, but to be able to see the poster, we have to give this image a class name of WFool.
00:05:02 And let's do something big like H 550 pixels.
00:05:07 There we go.
00:05:08 So now it takes that upper part of the screen.
00:05:11 Looking good.
00:05:12 We can also give it a resize mode equal to stretch.
00:05:18 There we go.
00:05:18 So now it is looking even better.
00:05:20 Now below that view, we can render another view that'll have a class name equal to flex dash call, items dash start, justify dash center,
00:05:33 margin top of five, and padding X of five.
00:05:37 We're just creating some space for the text elements that'll go within it.
00:05:41 So let's create the space for the first text element that'll render the movie?title.
00:05:48 And we can style it by giving it a class name equal to text-white, font-bold, And text dash Excel.
00:05:59 There we go.
00:06:00 Gladiator 2. We can go below this text and render another view.
00:06:07 This view will have a class name equal to flex dash row, items dash center, and a gap X of 1 in between the elements, as well as a margin top of 2 to divide
00:06:20 it a bit from the elements above.
00:06:23 Within this view, we can show one more text.
00:06:27 This one will have a class name equal to text-lite200 and text-sm.
00:06:36 And within it, we can render the year.
00:06:38 We already learned how to do that.
00:06:40 Movie question mark dot release underscore date question mark dot Split by the dash and get only the year.
00:06:51 Oh, but the index of zero has to come after the split.
00:06:54 There we go.
00:06:56 2024. Right below this text, we can render another text with the same styles.
00:07:01 So that'll be a class name of text-lite200 and text-sm.
00:07:09 And within this one, we can render the movie question mark dot runtime.
00:07:15 So this one lasts for 184 and we can add M at the end, which stands for minutes.
00:07:21 Now we can exit this view and we can create another view below to show some more information.
00:07:28 This one will have a class name equal to flex-row, items-center.
00:07:35 BG of dark 100, padding X of 2, padding Y of 1, rounded dash MD, gap X of 1, and a margin top of 2. And within this view,
00:07:50 we can render an image that'll have a source equal to icons, coming from constants icons, dot star, as well as a class name equal to size of 4. And there
00:08:05 we have it, one little star right there.
00:08:08 Right below that image, we can render a piece of text that'll have a class name equal to text-white, font-bold, and text-sm.
00:08:21 And within it, I'll put a dynamic block of code and round up the current score by saying math.round movie?vote?average Or,
00:08:34 if it doesn't exist, simply take 0, just so it doesn't break, and we can say out of 10. So this one is 7 out of 10. Right below it,
00:08:44 we can also render another piece of text that'll have a class name, that'll have a text-lite200 and text-sm.
00:08:55 And within this one, we want to show the number of votes.
00:08:59 So in parentheses, I'll say movie.
00:09:02 question mark dot vote count, and then I'll say votes.
00:09:07 So this one got 2,947 votes.
00:09:12 It matters, right?
00:09:13 We want to know how many people have rated it on average seven out of 10. And now we want to show a couple of these movie labels,
00:09:20 like the overview, release date, status, genres, and so on.
00:09:25 Each one has a little title on top and then the actual content.
00:09:30 That means that we can turn it into a reusable component.
00:09:33 So right at the top, I'll create a new reusable component and call it MovieInfo.
00:09:41 So const MovieInfo is equal to a function.
00:09:45 that'll destructure the props of label and value.
00:09:50 So for each value, there is a label.
00:09:52 They'll be of a type movie info props, which we can define just above by saying interface movie info props.
00:10:05 And it has a label of a type string, as well as an optional value of a type, either string or number or null.
00:10:15 Perfect.
00:10:16 And then we can open up a function block with an immediate return, which means that we just put parentheses right here and not curly braces.
00:10:25 So what do we return?
00:10:27 Well, it'll be a view with a class name of flex-call, items-start, justify-center, and a margin top of five.
00:10:40 And right within it, first, we show a piece of text that has a class name of text-light-200, font-normal.
00:10:53 and text-sm.
00:10:55 And within it, we render the label.
00:10:58 And next, we can have a text just beneath it with a class name of text-light-100, font-bold, text-sm, and margin top of 2. And within it,
00:11:14 we render either the value or a string of na.
00:11:19 Value doesn't exist.
00:11:21 And now we can use this movie info a couple of times right here below our view that contains the vote count.
00:11:29 So let's go right below it and let's render a couple of these movie info components.
00:11:37 The first one will have a label of overview and the value of movie question mark dot overview.
00:11:44 And if you self close it, check this out immediately.
00:11:48 It looks super nice.
00:11:50 Let's also render one more just beneath it.
00:11:53 This one will have a movie info of genres and the value will be movie question mark dot genres.
00:12:02 question mark dot map, where we get each individual G as in genre, and then we can say return G dot name, and then outside of that function,
00:12:12 we can say dot join them with something like a dash in between, like this.
00:12:18 Or say NA, doesn't exist.
00:12:21 So if you do this, you'll see action, adventure, drama.
00:12:25 Looking good.
00:12:26 Now let's create one more view below this movie info.
00:12:30 This one will have a class name of flex, flex-row.
00:12:37 justify-between and a W of 1 over 2, so that is 50% of the width.
00:12:44 And within it, I'll show another movie info component with a label of budget and a value of $movie?budget And we can divide it by 1 million and then render
00:13:02 the data in millions.
00:13:04 That'll look something like this.
00:13:05 Budget is 310 million for this movie.
00:13:10 Still within the same view, but just below this movie info, we can also show the revenue.
00:13:15 So the label of revenue.
00:13:18 And a value of, we want to do the same thing right here, but we can round it up a bit.
00:13:23 So we can say a template string of math.round.
00:13:28 Movie?
00:13:32 And once again, we want to divide it by 1 million and save it.
00:13:37 And at the start, we can add a dollar sign as well, right here.
00:13:42 So now we can see that the revenue is 458 million, which means that this movie is already profitable.
00:13:49 Finally, we can go below this view that wraps the two of them, and we can create one more movie info.
00:13:57 This one will have the label of production-companies and it'll have a value equal to movie?production-companies.map where we get each individual company
00:14:13 and for each one, we return its name and we can join them by a dash, which will look something like this.
00:14:22 Or if it doesn't exist, we can simply say NA.
00:14:26 There we go.
00:14:27 So now we can see Paramount Pictures, Scott Free Production, and more.
00:14:31 Many people worked on this movie.
00:14:33 Finally, just below this entire scroll view at the bottom, we can render a touchable opacity.
00:14:40 A button to go back to the previous page.
00:14:43 So it'll have an image.
00:14:47 That'll have a source equal to icons.arrow with a class name equal to size-5, margin right of 1, margin top of 0.5, and rotate 180, and a tint color equal
00:15:06 to hash FFF.
00:15:08 So if you render it, you can see it just yet, but below it, I'll render a text that'll say go back and I'll give it a class name equal to text dash white
00:15:24 font dash semi bold text dash base.
00:15:29 And now you can see it, but of course we have to style this touchable opacity a bit better by giving it a class name of absolute.
00:15:39 bottom-5, left-0, right-0, marginX of 5, bg of accent, rounded-lg, paddingY of 3.5, flex, flex-row, items-center, justify-center and a Z of 50. So it appears
00:16:09 above other elements.
00:16:10 And there you have it.
00:16:12 A movie details page with a go back button.
00:16:16 Of course, to actually make it work, we can use the router functionalities.
00:16:21 So let me give it an on press and call the router.
00:16:26 which we can import from exporouter.back.
00:16:30 If you save it and click go back, take a look at that.
00:16:34 It actually goes back, but you can also just scroll or swipe from left to right on iOS to go back as well.
00:16:43 And now you can see the movie details for all of these different movies, not only the popular ones or the trending ones,
00:16:51 but also the ones that you search for.
00:16:54 So if you have your favorite movie, I don't know which one it is.
00:16:59 Once again, let me know down in the comments.
00:17:01 Well, you can find it right here and see all of its details.
00:17:06 And I got to say the app is super, super responsive.
00:17:11 It works very well.
00:17:12 And you can see as I swipe up and down and as I open different pages, it is just super efficient.
00:17:19 And this brings us to the end of the movie details page.
00:17:23 And we're almost done with the entire app.
00:17:25 This is pretty amazing, I gotta say.
00:17:29 Just before we finish it off, I wanna make sure that we have something on the saved and profile pages too, because right now,
00:17:35 they look super blank.
00:17:37 So let's head over into those two pages, starting with the profile.
00:17:42 And I'll just tidy them up a bit.
00:17:44 So we have a nice blank screen, but then if you want to, you can go ahead and implement additional functionalities.
00:17:51 This is an exercise for you to improve this app even further and to put the skills you've gained from this video to the test.
00:18:01 First things first, let's get rid of this ugly white screen by rendering a class name to this view and giving it a BGPrimary.
00:18:13 as well as a flex of one and the padding X of 10. That's better.
00:18:18 Within it, let's also render another view, which we'll use to center our icon in the middle.
00:18:25 So I'll give it a class name of flex justify-center items-center flex-one flex-call and a gap of five.
00:18:39 Within it, we can render an image that'll have a source equal to icons dot person, and a class name equal to size of 10, as well as a tint color equal
00:18:54 to hash FFF.
00:18:56 Oh, and make sure to import the icons from constants.
00:19:00 And then reload the app.
00:19:02 While it's reloading, we can also add the text element right below it that'll simply say profile.
00:19:10 And we can style it by giving it a text-gray-500 as well as text-base.
00:19:18 So now if you head over to the profile, you see a little profile icon in the middle waiting for you to implement that profile screen.
00:19:27 What we can do is also copy this entire view, head over into saved, and override the saved as well, but this time it's not going to be icons.person,
00:19:39 it'll be icons.save, as well as it'll say save.
00:19:44 So now if you head over into the saved, you can see that it looks great as well.
00:19:50 Again, I don't want to simply give you everything in this course because then there's not going to be an incentive for you to try some things out.
00:19:58 So I invite you to go ahead and implement that save movie functionality to save your favorite movies into a collection.
00:20:06 You'll have to work a bit with AppRite to have some persistent storage and it'll be very similar to tracking our metrics right now.
00:20:14 Instead of searches, you'll be tracking the clicks when somebody clicks a heart on a specific movie, for example, and then you'll have to create a second
00:20:24 function that'll fetch all of the favorited movies.
00:20:27 Pretty cool, right?
00:20:28 I know it might sound difficult at first, but trust me, as you get a hang of React Native, it'll all start making sense very soon.
00:20:37 Especially if you dive into JS Mastery Pro, where we dive a bit deeper into how React Native works under the hood, as well as how we can optimize it for
00:20:47 bigger applications.
00:20:48 Great.
00:20:49 That's it for this lesson.
00:20:51 This was a big one.