Building Next Generation Applications with Next.js and MongoDB

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey everyone welcome to the september edition of the tracy developer meetup hosted remotely for the time being um so i'm the tracy developer meetup organizer i'm nick raboy and uh today we have special guest otto kuk from malhudibi there's an echo going on that was me it's all good uh yeah so the the topic of the evening will be next js and mongodb which is going to be pretty cool uh both of us we both work at mongodb uh but there's there's interesting stuff going on that otto's going to talk about but before we let otto have this show i want to go over some logistics so we are live this is not a pre-recorded video this is a live stream uh on youtube so please if you have questions engage with us in the chat i will be actively moderating the chat auto will be peeking in occasionally but i'll stop them if there's a good question that comes through if there's any kind of audio or video issues that i don't catch please drop that in the chat as well let us know about it early so that way we can fix it as i'll put out uh i'll give you more logistics towards the end of the meetup as well as far as the group and upcoming events things like that but i think for now otto the show is yours how uh why don't you give us an introduction awesome well uh thank you thank you nick thank you for having me at the tracy developer meetup um so a little bit about me my name is otto cookish and i work at mongodb with nick we both work on the atlas team we're both developer advocates and uh you know our day-to-day jobs are to help developers learn mongodb and um you know by night i am a huge fan of next jes and you know whenever i have some free time all i love to do is code and build some cool applications and next for me has made coding fun again so today i'm going to introduce you guys to um you know to next year yes the react framework for production uh if you're brand new to next uh this will be a great introduction uh if you're you know if you use next before or react before i think it'll be uh you know you're sure to pick up some new tricks and we're also going to use next with mongodb and show you how the two technologies interact and help you build your applications faster and better so um with that said uh i think uh we can just dive right in and as nick said if you have any questions comments if you want me to speed up slow down uh feel free to uh let me know and uh i have many monitors all around so if i'm looking at different screens i'm probably just looking at a uh at a comment or a doc or you know just trying to see what's going on um but with that said let's uh let's dive in so um you know before i before we get into the code and building some cool fun apps um answer in the chat if you've used nexjs before and uh if you have used nexjs uh you know let me know what your favorite thing about it is um and while we wait for comments to come in i'll tell you guys a little bit about react a little bit about next js uh what it is how it works and why you should consider using it for your next front-end application so i'm here on the nexus homepage and uh you know their big headline is that nexjs is the react framework for production and uh you know why that's the case you know we can look at the docs here and information and see um you know why what next js does and essentially what nextgs is it is a framework built on top of react so if you are a react developer and if you've worked with react before you know it is just a tiny library for building really powerful uh uis and user interfaces next js kind of adds all of those missing pieces it adds uh server side rendering and static side generation so that you can build an app that works really well with um with seo you know it has typescript support built in it has a file-based routing system so that instead of having to bring in another library to help you with routing of your spy application it's built in into next.js there's incremental static regeneration which we'll talk a little bit about and i think the coolest part about next.js is its support for api routes so as you're building your application you know you are eventually going to hit a a moment where you need to have some private data some private backend calls that you don't want living in the browser and with api route support in xjs you can add this very very easily and we'll see you'll see how all of this works so i'm just looking to see if there's any comments and uh hi roman thanks for thanks for joining i see you haven't worked with nexjs yet so today uh you'll kind of get a primer on it so we'll be working a lot with next js and i know i've been saying that next.js a lot so i'll try to cut it out uh the other technology that we're going to be using in our application is uh called mongodb and uh if you've worked with mongodb in the past uh leave a comment and let me know if uh if you worked with it what you think of it uh as i do a little introduction so uh mongodb and mongodb atlas is a software as a service database essentially and what this is going to allow us to do is host our database and host all of our data in the cloud without having to do any of the management of standing up and managing our own database and mongodb atlas it has a free tier which we're going to be using so if you're just building an application and just want to get started quickly i think mongodb atlas is the best way to do it and um we're going to show you how this works and how it integrates into next.js so so with that said uh let's dive right into building our application and uh building some cool building some cool stuff and as nick said if you have any questions uh you know shoot him in the chat and uh roman is tuning in from tracy so he is in california and uh thank you for your for joining the online um online meetup for now and hopefully uh i'm able to make it out to tracy in the in the future when we can have in-person events again so the best way to get started with uh next js is uh with the mpx package manager so i'm gonna open up visual studio code and we're gonna start by creating a brand new next.js application and to do that what we're going to do is run an npx command called npx create next app and what this is going to do is it's going to bring in all of the next.js dependencies and basically set up a sample app for us um the cool thing about this create next app uh call is that we can make it even better so since we're gonna be working with uh mongodb we already have a mongodb integration with next.js so to pull in all of that code we simply just pass in an extra parameter to the create next app call called example and we're going to say with mongodb what this is going to do is it's going to bring down the exact next.js application that already has our mongodb integration and we'll go over uh what that code looks like as we start building our app and then the last parameter we need to pass in is the name of our application and we'll just call it tracy app so with that command typed out and we'll hit enter and this is going to take a couple seconds to download all of our dependencies and then we're going to have an app ready to go in our new tracy app directory so we are ready to go there i will hit cd tracee app which is going to take us one directory over into our code and then we can run npm run dev to start our application but before we do that let's open up this directory so we can kind of go over it and explain what's happening so here we are tracy app we'll open that folder and yes we trust the authors our terminal again and let's before we start our application uh let's examine the code a little bit and let me see if there's any comments uh and yes roman this will be available afterwards and uh santosh welcome uh to the to the webinar as well so we just ran the npx create next app command which created a starter nexus application for us and before we run the application let's kind of take a look at what we have we have a bunch of our node modules which we don't need to go into it's any next node project that you work with is going to have a bunch of these we have this library or or lib folder which has our mongodb integration and we'll get into that in just a second and then we have our pages which has um our our starter basically our home page and that's pretty much it and then we have our public folder which has our favicon and the diversel logo and if we were to start this application up by running npm run dev we can see what the application looks like in in development mode so running npm run dev starts our application on localhost 3000 so let's go ahead and navigate there localhost 3000 uh it's going to give us an error and this is actually expected because we didn't set up our environment variables to be able to connect to the application so uh with that uh next js with example we are required to give it the mongodb uri otherwise it's not going to run so good just for the sake of being able to see this actual error can you zoom in just a bit uh yes i can so we can put two and two together sweet there we go thank you awesome so again you can see we have a server error and it says please add your uri to dot env.local so we can go back into our code here and there's an env.local.example that we can rename and we'll just get rid of this example so that we do have an environment variable that we can work with and what we need to provide it is our mongodb uri and at the moment we don't have a mongodb cluster set up so the next step we're going to do is go ahead and set up our cluster on mongodb atlas to be able to connect to our mongodb database so let's do that next i will open up a new window here and let's go to mongodb.com forward slash atlas and sign in let me zoom in as well it'd be cool if there was like a browser mode that said uh like special preserve the settings for certain scenarios button right unfortunately not so i am uh logging into mongodb atlas and um we have a question for i think this is a question or a statement i'm not sure um you could spin off a docker image of mongodb locally as well um would this work for the the given scenario that you're going over absolutely so uh in our next.js starter all it all we need is a connection to mongodb so whether you're hosting it locally so whether you have like the community edition installed on your pc or mac or you have it running in a in a docker container or your own cloud deployment wherever mongodb is hosted as long as you can get the connection url you are good to go and then this is in this instance we're just going to use mongodb atlas which is going to simplify all of that database management for us um to to make it happen so going back in here and let me zoom in so i did set up a cluster earlier about three hours ago for our tracy meetup and i did load some sample data in it as well that has a bunch of databases and these databases come pre-installed uh when you are working with mongodb atlas so if you um you know if you just want to try out mongodb and kind of learn how it works and you want sample data to play with there is seven or eight different repositories and we're going to be using the one called sample underscore m flicks for for movie flicks and what this is gonna have is a number of collections um containing movie data and uh you know reviews on the movies users uh who who leave comments about movies and stuff like that um but the collection that we're gonna be most concerned with is the movies collection and this is gonna have uh information about 25 23 000 movies are you able to zoom in slightly so that way we can get a good idea of what the data looks like yeah the this section is kind of small okay uh yeah i think that looks good uh if it's too small please drop us a message in the chat we can make it larger sounds good please let us know um so if we are looking at it we have 23 000 documents and this is kind of what our movies are gonna look like i'll zoom one out just so we can see the um the documents and the fields within the document so we have an underscore id for the id of the movie the plot of the movie its name um it's cast you know the genres that it's part of where where the movie has been released and it's imdb information um run tomato ratings and much much more so each movie has kind of a similar schema some of them are going to have more information than others but we have a whole bunch of movies to play with so now that we now that we've looked at our database we looked at the data that we're going to be working with let's figure out how we're going to connect to our cluster so i will go back to the databases section and hit this connect button and what this is going to do is first of all it's going to tell us that we can't connect yet because we haven't set up our uh so we haven't enabled the marmodb atlas firewall access rules to allow a user um to access our database so i'm going to add my current ip address which is going to allow my instant you know me to connect to the database and then let's create a user and we'll call this user tracy for example for the tracy meetup and let's add a password so now that we have our ip address so now that we know that mongodb can connect from my ip address and we have a database user we're ready to connect so we'll choose a connection method and in this case we're going to connect to our application we can connect be a mongodb compass or the shell if we just wanted to execute commands but since we are building a full application we're going to connect to our app and what we're going to want to get from here is our connection string so this mongodb plus srv and then the long string to our cluster i'm just going to copy that go back into uh visual studio code and paste it into our mongodb uri and then let me also [Music] view word wrap now the last thing i need to do here is add the password so it pre-filled our username but the password we need to provide here and i think that's it for password as mongodb save the file and i will restart the application so that it can properly load that environment variable and connect to our mongodb instance so clear this here run npm run dev again and we'll see a message in here that uh we loaded our environment variables uh from tracyapp.emd.local so we didn't have to do anything extra next she has handled all of this for us by by just having the env local file it knew that we probably had environment variables we wanted to work with and it loaded them and then if we look at our well actually let's take a look at the application and then we'll get back to um seeing where this environment uh variable is being used so let's go back into our code here and now it automatically refreshed and gave me the kind of default next js welcome page saying welcome to nextgs with mongodb and it also gave me this message saying that you are connected to mongodb and to get started you know building your application start by editing the pages for slash index.js route so let's take a look at this code here so if we open up pages index um and let's just change this welcome to welcome tracy that save go back into our app we we can see that we automatically updated that message and next js has uh kind of built-in caching validation as well as live reloading so every time we make a change to any of our code it's automatically going to rebuild the application for us automatically that's kind of another nice thing that's just built into next.js and then to see that you're connected to mongodb message we check a variable called is connected that gets fed into the home component and to see where this disconnected message variable is coming from it is at the very bottom here in this get server side props method and the way that uh get service iprops works is in xjs we have multiple ways of working with our data so we have multiple ways to to fetch data so if you're building a just you know if you're treating it like any old react application you don't have to use get server side props and what's going to happen is you would have to get all of your data up here in the in the actual function itself so we could you know do a fetch call to an api to get data and then uh load it into our view [Music] and we could you know use stator or probably put it in a use effect uh if you have it run once but with next js we have this special function called get server side props and what this is going to do is it's going to make that that page this index page um render on the server and this is the first function that's going to be called and the code in here the first thing it's going to do is it's going to await this client promise once we have the client we're going to call the disconnected method on it and this client is our mongodb database connection and if the client is connected it's going to come back true if the client is not connected it's going to come back false and then we just pass it as a prop into our home component so again if i scroll up here we can see that we're capturing that disconnected prop we're just deconstructing it from our props and then displaying either you are connected to mongodb or you're not connected and check the readme for instructions and then that client promise that's coming from our library mongodb package so let's go ahead and take a look at what that code looks like and and what it does so i'll open up mongodb.js and here we are using the first thing we're doing is importing mongodb and the client so if you work with mongodb with you know node.js in the past we just brought in the mongodb package and we're getting the client out of it and then we are getting our uri from the environment variable so our mongodb uri setting our options for the connection to mongodb using the unified topology and the new url parser and then here's where that error we saw earlier when we didn't have the uri defined if we don't have it it's going to throw up a server error telling us we need a uri before we can connect and then for performance reasons we check to see if we are in the development environment and if we are then we create a client promise and set it to the global variable and what this is going to do is it's going to keep our mongodb connect keep our connection to mongodb active even as that server rebuilds um and this was kind of a performance um a performance best practice that we found works best with next.js because every single time you make a change if you don't have it in the global variable it's going to make another connection to mongodb and it's going to kind of you know eventually if you're making too many changes too quickly you're going to hit that connection limit and it's going to uh you know manga is going to start running very slowly but if you are not in production in development mode if you're in production then we are just going to go ahead and use the new client pass in our uri with our options and call client.connect which is going to be that client promise and then we export it so this is all the code we need to get our to get our connection to mongodb and be able to talk to a mongodb database and let me know in the comments if you have any questions so far if any of this isn't making sense or you know if i'm doing a good job let me know as well so we'll close out the mongodb.js and we can close out our environment.local variable and one other thing i want to do here really quickly before we move on is add tailbone css to our project and i'll just do it the simplest simple cdn way and that's going to allow us to make our ui a little prettier so let's see here i'm going to [Music] get a url [Music] go in css and we're just going to add it here in the head of our next.js application and this is another uh unique thing about nexjs is there is this special component called next called the head component that comes from next head and this allows us to set up any of the head metadata in our next.js application so title link any scripts that we want to bring in or anything like that and in this case we're just adding the um tailwind css package um otto question you just you just included the actual minified css for tailwind what if you wanted to include their package version so that way you can do stripping of components that you don't need etc is that possible absolutely yeah it is so if we wanted to install and i should actually show you how to do that as well um so let's see does and does tailwind not tailwind does uh the next js framework that you've set up does that include everything necessary to actually uh do that uh what post css typically does and uh etc to strip out things you're not using so yes if we were to go through the multiple step process of adding um you know the proper tailwind css to next.js then yes it would you know we would add post css and i could actually probably do it it's it it'll take like two seconds but here we'll open up a new terminal window oh is that fast let's do it for sure yeah uh i will run npm install uh kelvincio says the latest version we'll get post css and auto prefixer that's right off their website right yep so i'm on the tailwind css website and i'm just going through their list of commands um so the first thing we need to do is install uh next js that looks nasty let's see what happened here is that terminal that you're using uh inappropriate for npm or uh it shouldn't be let me try it one more time there we go that was weird yeah you know how you know how mpm is sometimes you just gotta run it twice so once we have our defendant so once we have our npm dependencies of tailwind css post css and auto prefixer the next thing we're going to do is run npx tailwind css init and what this is going to do is it's going to create our code css config file with television css not a prefixer as well as our tailwind.config.js file where we can add any additional tail and css plugins we can decide which pages to purge uh add any of our variants any theme extensions etc etc and then i think the last thing we need to do [Music] is just include tailwind css in our global styles so um [Music] we can do [Music] or actually we can actually just pull it in right up here import elements here it says from uh the tailwind css npm package and then we should be able to delete our link here and let's see if we might have to restart the app because of uh post css and the tailwind config let me do that and if we go back to our application let's see if that changed anything [Music] uh it looks like it did so our our ui looks slightly different but let's try a tailbone css command and see if it works so let's do color green 500. back to our application [Music] did it not work ah let's see what we do um this title being overwritten there we go so that worked i might have my uh [Music] the text screen i was gonna say wouldn't that make it the same color it would there we go um we have kelvin css installed now uh it is running and we we built it the way uh the way you're supposed to if you're planning on using tailwind css you can't do it via the cdn way but for for our use case we'll uh we'll bring it in the the proper way and show you how to do it so we're good there um for the next part let me go ahead and clean up all of this kind of starter code like we don't care about the default kelvin css style so i'll remove those and i'll just remove all of this extra code now [Music] let's say h1 modern apps with xjs and last name of text five excel so there we go we are looking good there and then let's also add a container here inner mx auto and these are television css classes that are going to help us center our content and make it look good class name container what am i doing wrong the joys of live coding right oh it looks like because we have two containers we're having some discussion in the chat about what's so good about tailwind you want to give your uh your two cents on on why tailwind is so great sure absolutely uh i love tailwind css because it is very unopinionated in uh how you build your uh so it just gives you a bunch of utility classes to build your uis uh which i think is superior to like bootstrap's model of giving you kind of pre-built components and then when you go to edit those components out you start running into uh you know issues with overriding styles and it's just much more difficult to build scalable ui components i feel like with next j or with l and css uh you just have a bunch of utility classes for your padding for your module margins for your layouts and uh you just you know you end up writing a lot more classes in your code but i think it makes it much easier to build unique user interfaces and then when you have a component that you're happy with you can very easily extract it into an actual component um with kelvin css and then you can just use it with you know a few classes um so i'm not i'm a huge huge fan of tailwind but um yeah that's my that's my quick spiel on uh tailwind and uh so i am zoomed in so that's why it looks like not much has changed but yeah we we can see that the mx auto class um with margin left and right is set to auto and our container with the max with 1536 is set these are tailwind classes so we are good to go the next thing i want to do is bring in some data from mongodb because right now we are uh getting access to our uh to our mongodb client and we're just sending back that message saying are you connected or not but that's not very interesting so let's get some data let's get some actual data uh from mongodb from that uh mfx collection from that movies collection and display it in our application and show you how easy it is so the first thing i'll do is i'll create another variable for my database so i will do cons db equals client.database and then give it the name of my database which in this case is um let's browse our collection here it's going to be called sample underscore and flicks so we'll go back in here say sample underscore and flex now you don't necessarily have to do it this way you could you know write client dot db sample netflix and then run the command but i find it always easier to uh create another variable for your database it just makes it a little bit cleaner to to write your commands so now that we have our database variable we can use it to execute mongodb commands so the command i'll write is let's say const movies equals database dot find and i'm not going to pass in i'll just pass in an empty object for our movies um so we'll just get the first 20 movies in our collection and we'll set that to an array so that we get our movies uh in an array otherwise if we don't call this to array method what's going to happen is we're going to get back a cursor which we would have to manually iterate over to get our data and from here let's get rid of the disconnected and we'll just send back our movies and up here we'll say 12 as our prop and since this um this command returns a promise we are going to await it so we're going to say await bb.find um and actually we forgot our collection so we need to do db dot collection so which collection are we looking at if we go back to our code here we have comments movies sessions theaters and users we want the movies collection and then we're going to run the dot find an empty empty object meaning just get it give us the first 20 and not limit it to the first 20 otherwise we're going to get back all 23 000 movies and we'll be uh we'll be sitting here for a minute so with that said let me delete all of these comments it's not confusing we'll hit save and now when we go back to our application uh we should see uh our our list of 20 movies and actually let me just also log it here so that we see it in the browser going back into our application hitting refresh we are going to get an error and again i anticipated this this would happen but i wanted to show it to you guys and show you why it happens and how to get around it so the server error that we're getting is a serializing error saying that movies uh movies at index zero uh underscore id return from get server side props cannot be serialized please only return json serializable data types now the reason that this happens when we call get server side props in next js is that the only things that we can pass into our components are just plain old javascript objects and we can't pass in any special data types that we get back from mongodb like the underscore id um so there is a kind of hacky work around for this and uh i've been working with the nexus team to see if there's a better solution for it but the solution for now that i found is we'll rename we'll rename this const movies to const data and then we'll set a new variable called const movies and what we're going to do is we're going to first jason stringify the data that we get back and since we want to be able to work with that data we're going to parse it so i know this looks a little ugly but it does work so we're gonna first json stringify our data which is going to convert forcefully convert all of our data types into uh you know plain old javascript objects and then we're gonna parse those and make them make them objects that we can interact with set them to that movie's variable or constant and then send it as a prop so i will hit save here go back into the application and let's open up the console here to see if we got our list of movies and we did so so far so good uh we got an array of 20 different movies we got all of the information about the movies uh so here this is blacksmith scene it's unrated um there's the the plot for it and etc etc so we have our our movies but let's display it in our application i think it's fun seeing it in the console but it's much better seeing it in the actual ui so we'll go back in here in our uh home component which right now we are just going to be working with um react so if you're familiar with react you should go right at home uh let's create a new container and what we're going to do is use tailwind components to create a grid so let's say they've class name flex flex and we're going to create um let's say if we have movies and uh if we have movies we're going to map over that movies array we're gonna stop that we're gonna get an individual movie and then let's just for now display the movie name h2 movie dot title and let me just make sure this is all right components so now when we go into our application we should see our list of movies that the 20 movies that we got back from mongodb and uh right now our ui's a little ugly so let's go ahead and fix that up a little bit so [Music] i like to do is always use these blank curly curly braces uh to make react happy and then we can go crazy in our ui so let's go ahead and create a width of say a fourth of the page but a little bit of padding say 16. um get a border and let's see what that looks like in our app okay so we we got a grid four by five we got our 20 movies uh and it's looking a little better let's also [Music] add some margin here so margin y okay cool so so far so good we got data from mongodb we we have uh we're using kelvin css for our ui and everything is looking good uh does anybody in the comments have any any questions anything specific that they want to see uh if not i'll just continue building uh what i had in mind but uh if you have any questions or if there's anything that you would like to see in regards to nxjs please let me know but uh now that we have our data let's see what we can do with it so i'm going to look at the console and see what interesting information we get about the movies so [Music] let's see um and nick if you have any any suggestions as well uh open i'm taking requests um no i'm still i'm still learning next js i i know i've seen you do it a few times i've seen other people do it a few times uh it's still wizardry to me maybe because i don't do that much javascript stuff anymore but uh it's pretty pretty dope sure well uh then i will continue and yes please as uh as questions arise please please ask in the comments or nick uh let me know uh what you want to see and i will do it uh roman asks why was there empty brackets um where did we have empty brackets these right here uh i will assume these empty braces so um when you i'll just assume that you were asking about this and if it's not plea please let me know and i will clarify it but the reason that we put empty brackets and we didn't have to put empty brackets in here um in the find command what we can do is filter our uh movies based on all sorts of criteria so any of the attributes here in our movies we can filter our data on so let's let's just say we wanted to get you know movies that were released in a particular year what we can do is in the brackets here we can say i give give me 20 movies that were released in 2011. so this is going to change all our list of movies and the first 20 movies that were released in 2011 that we have in our database is what we're going to get back and let's just confirm that that did work i'll refresh here and as you can see we get a whole new list of movies and um cowboys and aliens know me and julia these do look like 2011 movies but we can confirm it by actually let's do it in here we can say uh paragraph release date is movie dot uh yeah i believe is the field so if we go back into our application we can see that all of these excuse me all of these movies were released in 2011 and we can run multiple filters so we can say uh you know get me all the movies released in 2011. and um what are some other interesting areas to filter on uh just popped up again um he was referring to line 23 of your code rather than that fine statement line 23 oh okay so the empty brackets here are um when you create a react component uh you can you have to have one top level div so you know in this case i guess i didn't need it i could remove it and it's gonna work just fine but let's just say i wanted to have another top level div here doing something else right blah blah blah it is going to complain and if i hover over the error it'll say the jsx expression must have one parent element and if you don't want to use a div if you want something that the browser is going to ignore then you can just pass in an empty uh empty bracket and that's going to take care of it and then you can have as many uh kind of parent divs at the at the top level uh excluding this top level bracket so that's why i did that it's just a force of habit for me and uh now you can see that we we get that user interface um cool but uh yeah so let's see what other areas we can filter on so we're filtering by year here and we can you know change it let's say maybe 2013 and um let's say movies that are that have a longer runtime or let's do something more interesting let's say movies that have a high imdb rating so we can pass in another expression and say movies that are um that have a rating and i think they're rating so it's imdb.rating so we'll say imdb.rating so if you are working with uh mongodb data you can have uh you know you can have one-to-one relationships which is a field and a value you can have objects so here we have a field imdb that is an object that has multiple fields below it you can have arrays you can have objects within objects you know you can go as complex or as simple as you want but when you want to access data or filter on data that is nested we use the dot notation so here we're going to do imdb imdb.rating as our second filter and we'll say we'll run another operator called greater than and let's say 7.5 so what this is going to do what this query is going to do is it's going to find movies that were released in the year 2013 that have a 9 db rating that's greater than 7.5 so let's see if there were any good movies released in 2013. we go back refresh and we get a bunch of new movies and let's just confirm in our ui i'm waiting for the movies it's movie.imdb.rating i'm back in here and as you can see all of the movies that we have now are 8 7.6 8.2 7.6 etcetera etcetera so everything is greater than uh greater than 7.5 were there any really good movies release let's say greater than nine refresh and it looks like 2013 was not a not a good year for uh very popular movies so let's drop that back down to maybe an eight and now we get this list of movies so none of the uh marvel movies were released in uh 2013 i feel like all of those get higher than an eight no or unless that was thor dark world or something that year well you know like superhero movies they're great they're such a fun time but i feel like they never do really really well critically maybe i don't know i feel like that they're used like even the the good marvel ones they're still hovering in like the seven eight range i guess the academy doesn't look too highly upon uh superhero movies that's that uh martin scorsese is doing that right he's anti-marple um cool so now that we've shown how to get data from for mongodb uh let's show off some other cool uh next.js features so the next feature i wanted to kind of go into is displaying information for just a single movie and this is going to highlight how we uh how routing works in xjs and it works really really simply you just create a new file call it whatever you want the new page to be let's say movie [Applause] save it and you just create a component here i'll just copy everything i had on the index page for now save it and now we can [Music] go to the movie route and it's going to load in the same information and you have a compliment you have a compliment coming in from tejas i'm not sure how to say that name hey taz uh great to meet you and uh yeah you're very welcome if you have any questions please uh please send it my way anything you want to know i'm happy to cover uh so here let's just say this is the movies page we'll hit save and so if we go to localhost 3000 forward slash movie we get the this is the movies page if we go back to our index we get the building modern apps and if we go to a route that doesn't exist let's just say something like this we're going to get a 404 page not found because that route doesn't exist now so this is if we wanted to have named pages right so if we wanted to have a page called movie or about us or contact or something static we could do it this way but what if we wanted a dynamic route you know we might want uh the user to be able to put in a movie id and get a movie create a you know get that get information for that specific movie to do that what we would do is simply rename our route and actually i'll just create a new one and what i'll do is open up curly brackets and then js and we'll say movie id and again i'll paste all of the information for the component just so that i don't have to build it from scratch but now we have this movie underscore id slug created so what this is going to do is now any page that we go to [Applause] i'm not going to get a 404 we are going to load this specific rod because this is this axe essentially is a catch-all and it actually gives us the movie id which we can capture and to capture that what we're going to use is the next router so we'll import uh router right or now we'll import use router factor from next router and when our component gets loaded here and we can just rename it for for clarity we'll say movie details uh no we don't need to change anything else first thing we're going to want to you to do is get access to our router so so call this hook and the way we're going to do that is we'll say const router equals equals use router and then we can say const movie id equals router dot query number this console log the movie id let's see if this works so go back into the app here inspect and there we go we have our movie id which in this instance happens to be aksdfjsk but that's because that's what we put up here and if we change it to let's say numbers one two nine three four one two again our query is uh here so so we're able to capture our query parameter and display it in our component now to get information about this movie what we could do is run the get server side props get the um [Music] get the id here and make a call to our database and uh that would be i think that's the sensible thing to do but since we're here to learn next js uh why don't we do something different just to show you different ways of interacting with data with um with mongodb and xjs and what we're going to do is create an api route so in next.js if we create a special protected directory called api what this is going to do is it's going to allow us to create api endpoints um that run on the back end and execute data so what we're going to do is create an endpoint create essentially a restful http endpoint to get specific movie information and so we'll call it uh movie details [Music] and the way that this is going to work is in our movie details component we are going to export a default function call it a handler that's going to take a request and response and just to make sure that this uh api route works i just respond with a message of it works so now if i go into my nexus application go into the api endpoint and call movement details i'm going to get a restful http response that sends the message of hey it works now the cool part about this is in our index in our movie id in our movie.js we are using the we're bringing in this mongodb library and we can do the same for our api components so we don't have to do any extra wrangling any extra setup in the extra configuration we simply just import our client promise from mongodb and here we're going to have to go one library up and from here on out we can use mongodb in our restful components as well so what we're going to do export default let's see here sorry we could just copy this exactly as is so get our client promise from the mongodb library and then get an instance to our database which is sample mflix and then since this is an await uh this function needs to be async so we're going to export default async function and that should all work and just to make sure that it does let's run this same query here and we'll change it in a second but i thought i had wrap enabled um get our data and then we'll just send the data in our response so all we did was copy our code from the get server side props send it into a api restful component and then send that data so now if we refresh this movie details we get our movie information in json format that we can work with but what we want to do in this movie details page is get information on a single movie based on the id of the movie that the user provides so let's go in to visual studio code and what we're going to do is capture the query parameters and i believe it is uh let's say theory is request query but what whatever our um id is gonna be so let's say movie underscore id let me just make sure that that one is correct so if we go and call movie id of the parameter one two three we should see our query being one two three and we do so we are good there and now instead of running this find operation which is going to get a list of movies for us we just want to get the specific movie that we ask for so we're gonna say instead of find we're gonna say find one and we can get rid of the limit and the array because we're only getting one item back and our filter is going to be on the ib field and it's going to be that query but we are also going to run into an issue if we just do it this way and i'll show you what that issue is so let's uh go back to our application copy a random id here use it as our id we have a question coming in too auto so now that we introduced an api shouldn't we rewrite the ui part to not use mangu directly but go through an api instead we will oh all right perfect [Laughter] we will and that is a good point so so the next.js team they actually recommend if you are writing api endpoints um to do it in git server side props but i just want to so you know if your react component is needs data that comes from an api it's you know the recommendation is to use get server side props since this already runs in the backend and is never exposed to the client uh to run it and get server side props but if you wanted um api functionality you know you wanted to make a restful api that anybody can consume then doing it the way i'm doing it right now is the way to go but to show you why this wouldn't work um so i've just copied the id for the waffle wall street and i'm going to hit enter and this isn't going to return back any data and the reason for it is this query parameter is a string while our object id in our database is actually an object id so it's not a string so what we're going to need to do is convert our string to an object id and to do that what we're going to do is very simply let's see here sorry i'm getting all my windows mixed up what we're going to do is wrap this new query since it's already a string that represents our object id we'll say new object id and just wrap it in parentheses and we're going to have to bring in this object id from mongodb so we can say import object object id from mongodb so now we should be able to get information on just a single movie and i can remove this query back in here fingers crossed refresh and boom so now we get information on just a single movie based on its id so in this case we have the wolf of wall street so now let's go back to our application let's go to localhost 3000 and this pass in our id so we're getting the movie details let's update this component to get information on just that single movie uh being the waffle wall street so what we're gonna do is go into our movie id page right here and we can use effect from react so let's say import use effect and then how do we want to do this so when our application is run we're going to get the router we're going we're going to get the movie id um and we can actually say use effect function and we only want this to run once so we'll pass in an empty uh set of brackets here we'll say fetch uh and it was let's see this for now movie details movie id and we'll hard code it for now but we'll fix it in just a minute and we'll say const theta or x and cos theta equals fetch and then since we can't use async await in a use effect we'll say data dot then [Music] i think movie right uh let's run it and make sure we're good and if not well we will fix it the joys of life coding um inside the body that's gonna happen so we did get an error uh what did we do here's a fact calls an empty function rid of all of this try it out okay so hooks can only be called inside of the body of a function component i'm doing something funky so let's see um i feel like it's right and uh nick if you know what's going on feel free to jump on and help me out um i haven't spotted it yet but i did put it in the chat to see if anyone else can spot it well i think one thing we can do since uh use effect is not cooperating with me we can actually go down to our get server side props and run the fetch command so just so i don't waste your guys's time on [Music] on the stream let's just copy this and we'll go down here we could remove all of this code we'll say fetch and let's just make sure we get the and now we can actually await this and we'll say send our movie via props and some and then we don't even need the router up here because we're going to handle all of it in our git server side props function so let's just make sure that this works and then we'll go back and clean it up uh more errors cannot resolve dns that's fine because we are bringing the mango library and not using it and movies get rid of all of this awesome so it does work so now we are calling a fr from get server side props we are making a fetch request to our api movie details passing in our movie number uh our movie id getting that data and then passing it in as a prop so we'll say movie details for movie dot title and let's just display the movies picture here let's say image source exists and let's see what that looks like so we got uh movie details for the waffle wall street um and the posted for the movie but we could put anything in here and we'll always get the waffle wall street because we have hard-coded the movie id here and we can fix this by getting i believe it's uh let's see context i think it's query let me just lock this whole object here see what we get oh we don't need um actually i think there might be a simpler way to do it free yep so context.query context.query.movieid is what's going to allow us to get the specific movie id from our movie id route and what we're going to do here is is hectics and then we will [Music] add the actual query context our query that movie id for our movie id so now uh we're gonna you're gonna have to pass in a movie id that exists to be able to see the information for the movie so in this case let's go and get it for the wolf of wall street and we get what we'd expect if we go to the home page and let's get a different movie um this case i will get let's say this movie get its id boom that works so now we have another route that has information for our movies and if we were to pass in a bad id uh we're gonna get an error because uh [Music] because we didn't get uh data we didn't get a successful response back from our api call we got back an empty object which we couldn't serialize into json so um our app is gonna crash which is to be expected we're just doing a quick demo app not doing a whole lot of uh error handling um cool so so that's uh file based routing and adding dynamic links and dynamic pages uh i showed you how to build an api endpoint so that's looking good the the final thing i wanted to show [Music] unless anybody has any specific questions or requests is um static site generation with next js and i think this is probably one of the coolest features of next.js and what this allows us to do is generate our pages ahead of time so let's say we had this list of 20 000 movies and you know the data is in there and it's not changing it's not going to constantly change so what we can do is generate all of these pages at build time so that when we deploy our application uh when a user hits a page uh details for a specific movie what it's going to do is it's just going to serve html it's not going to make the call to mongodb there's not going to be that round trip to get the data populated it's going to do all of it at build time for you and it can with incremental static regeneration it can get new data as it's added to the database and refresh it but your end users are always going to see the latest and greatest version of the data loaded super super quickly and to show you how this works let's go into let's create a another page and let's see how do i want to do this bear with me for just a second um yeah you know what we can do this movie underscore id so what we're gonna do is we're gonna re-um [Music] remove the get server side props which always runs every single time when a user hits your page uh this runs on the back end generates the content and serves it we're going to get rid of git server side props and what we're going to use is another special function in xjs called get static props let's say export async function get static props parameters and what we can do is pretty much all of this data copy it and move it one up and here we'll say params dot movie id everything else can stay as is we'll get rid of get server side props and the other thing we need to add in this return statement is a another property called revalidate and here i'll set it to one now what this revalidate method does or or property does is it tells us how often to check if there's new data on for the application and by default uh you know if we set it to zero it's going to generate a build time and then that page will never be updated again if we set it to one then every second um it's gonna make a call and see if there's new data and if not it essentially treats it like a um like a regular database call but let's say we wanted to do it you know every 60 seconds or maybe once a day you know we would do like 60 60 by 24 so now every um every day we'll get new data um and if it exists if not it's just going to continue serving that static page but for now let's just change this to one and uh we need to do one more thing with the get static skid static props method and that is to add a get static paths method these two need to work together to to enable static regeneration so the way that this function looks is export async function get static paths and here we're going to return our paths as an array i'm going to set back the fallback to true now by default what we would do here is we would populate all of the known routes so all of the ids that we wanted to build ahead of time we would populate in this past variable so we could you know call mongodb go to mongodb get a list of ids populate it in the paths and then add build time build the pages or we could leave it empty and just have this pages built as they requested so that's the the option i'm going to opt for so we're going to leave the paths array is empty and we're going to set this fallback property to true which means that if a page isn't already statically regenerated go ahead and run the get static props and get the information for it and build the page so i'm going to hit save here and refresh our page here and we did get an error and i think that's because the params are wrong [Applause] just double check french lots errors [Music] pages movie id type error uh what are we missing do you need to do a console log to see what uh what's oh you just did i just did but i'm not but it's given a problem about title though that's because uh the movie title here so the movie didn't get populated so i'm pretty sure i messed up the params it perhaps has an id it's printed out i don't see it uh let's see if we can debug this real quick params.movie id params.movieid is what should be fed here if you're printing it out in the online 39 shouldn't we see it yeah but we don't so let me [Music] my favorite way of debugging right yeah uh so where is that hello my my i usually say made it here right here here here um i don't see it i don't see it either and we're sure the function is called to get static props is that spelled correctly good static props get static paths on movie id movie id yep so let's see what are we missing we could figure this out um this is where my lack of uh react knowledge comes into play and if anybody in the comments has any suggestions we are all ears uh let me restart the app and uh maybe sometimes that works just like npm install sometimes a hard restart and fix things if you're having a hard restart everything i think i think the problem might be you and not mpm it might be you can do some windows updates what do you use an npm version for something oh gosh i don't even update those chocolatey packages pm6 i don't i don't know if that's good or bad i honestly don't know either um so we get the same error and actually i'm on npm seven point something so that's a little old yeah uh okay so let's kick in some debugging skills uh oh let's say this i've movie we got alex in the chat saying that we're at eight at least we're both pretty ancient over here i guess so let's do ha so that was it so wait go back what was the problem i missed it the problem was um the get static props method gets called later uh so unlike the get server side props which runs before the component is built the get static props runs kind of asynchronously uh as the react component is being built so our movie didn't exist doesn't ex movie dot title doesn't exist until this gets resolved and gets populated so sweet that's what happened uh so it wasn't an issue with our code it was an issue with making sure that movie did exist and was populated before getting movie title and the movie poster um so that's the cool thing about git static props if we look at the next folder now under static here and pages let me see if i could find it right here so calling that get static props method actually generated a separate page for that particular movie and if we look at another movie let's say [Music] um in here i'll get [Music] let's get batman movie so we get batman.net returns part two if we go into the pages directory here did it get rebuilt refresh where'd it go or did it get added on uh server pages next i don't know where it went but it does generate a a static page for it and to show you that that does work if we were to so right now we have um batman dark knight returns and uh this bog milka bog movie uh as static pages and if we were to go in here and set the file back to false meaning that if the page isn't generated at build time don't go and get it we should still be able to nope we don't so because it did rebuild um the application so with the fallback set to false if the page isn't generated at build time because we didn't specify it here um and actually let's do that so if we pass it in okay to build it at build time our page should be available does not match the page movie id oh is it there we go so with the fallback set to false if we say generate this page statically it's going to be generated and it's going to exist but for any other movie like the batman movie now we're going to get a 404 page now found because that page wasn't uh generated ahead of time and we have the fallback property set to false and if we change that to true now we should be able to get the batman page to load as well so that's kind of a really unique thing and then with the fallback as well or with the revalidate um as we update information like if we were to go in and update the title of the movie and we have the revalidate set to a high number then that change will not be automatically reflected um so yeah that's that's increment that's static set regeneration and incremental regeneration uh so all of that works and uh yeah so i think we've done plenty of things so far does anybody have any questions uh in the chat or um nick do you have any any questions any feedback anything you'd like to see if not we can uh slowly wrap it up and i can throw up the code on github if anybody's curious or you can just download the uh the next yes example and go from there i don't have anything i want to see um this this is all pretty good and a lot to take in um especially me not knowing too much about the subject um but we'll leave it open for questions in the chat i mean don't be shy this is a supportive group if you have a question please ask it this is your opportunity yep anything you know related nexus related tailwind css related react related i um those are all technologies i work in almost almost daily um so happy to have happy to help in the meantime i might update my mpm version to eight plus um cool i'm trying to think if there if there's anything else really unique about next that i can show in just a few minutes because i know we are running up on time let's see i guess on deployment that local host call will break um yeah so if you wanted to um again if you were building a real world application you know the nexus team recommends that even in get static props or server side props you can actually drop in this code and it'll work just fine so you don't have to make the call to localhost but if you did want to call it then what you could do is in an environment variable you could say you know whatever my app is um you know app app domain set it to you know http.com and then you would just replace that with um [Music] process.dnb.myamp so then when when your app does get deployed depending on your environment if you're in in localhost or in production it would get the proper domain and then it would uh call it up does that uh does that answer your question roman and the other i guess i can't show one really cool thing uh with next.js before we we close up i'll just revert this um in the local variables um by default all of these variables that you define here are protected they are never sent to um the browser so if you wanted to access any of these you can access them in your api routes and get server side props but you can't access them in your components but if you did have a variable that that you know was going to change from environment to environment and you wanted to be able to access it in in your react components you could do uh next public and then uh you know like let's say google analytics is a popular one so you could say ga equals one two three four five six so having this next underscore public prefix on your environment variables means that you can actually use it in uh the react components and they are going to be exposed to the front end so here on the let's see on the index home page we can do console.log process.env dot next public va so you know let's say we had google analytics set up and we wanted to change it from staging to production to our local dev environment we'll be able to access it in both uh is this the homepage it is we got an undefined because with environment variables you need to restart restart the application to load any environment changes so let's make sure that that did work this building and boom so now we we can access our environment variable both in the browser as well as in the backend so with server-side props or api routes just by using process.env.next underscore public uh [Music] so that's pretty much all that i had planned for today um thank you guys so much for uh tuning in i hope you enjoyed it i hope you learned something new and uh if you have any questions you can follow me uh cookiechado on twitter or find me on the mongodb community or really just linkedin you know whatever whatever your platform of choice is i'm on i'm on all of them dude this is great um so then while we wait for maybe last minute questions to trickle in um i am going to share my screen to go over some group logistics um so let me start sharing it alright is my screen visible to everyone almost no it's not still autos my bad all right now now my screen is visible to everyone i'm pretty confident of it so this is the tracydevs.com website it is the meetup group website if you're new to the group this is where we list all of our events which are also found on meetup.com eventbrite but tracydevs.com is the single source of truth when it comes to the events they'll show up here first uh we are looking for speakers for the remainder of the year um so if you're interested if you're if you feel like you've got something interesting to share and you you want to share with the group we'd love to have you it doesn't matter your skill set or how proficient you are with the technology and you don't have to be in tracy's uh i expect that we're going to be remote for the rest of 2021 so don't let the location deter you um for october i'm in the process of um finalizing a a presenter from uh vonage so we're going to see some various vonage apis and services for for messaging and things like that which will be pretty pretty interesting stuff but but beyond that we're still working progress for for lining up speakers um but go ahead and subscribe to the mailing list um so the mailing list i only ever send out two messages per month on the mailing list so the first message is a reminder that an event is happening so such and such week and then i also send out a follow-up email after the event with the on-demand video link so those are the only two messages that you're ever going to receive from this mailing list so you won't receive any kind of spam or anything like that and the reminders are helpful so please go ahead and subscribe to that as well while you're there that's all i have as far as logistics go it doesn't look like any other uh comments have trickled in so auto i think this is great um you said you're gonna share your code do you want uh do you want me to wait on sending out the uh the recap email until you have everything finalized um yeah i could get it up over over uh the weekend and maybe monday we can share it out that'd be great i'll include the link after you send it to me sweet and uh who just curious who is the uh guest from from bonnage do you have a name yet uh so i don't have a name yet i'm talking to the director over there he's gonna sync me up with someone over there if you know of somebody in particular that would be worthy of coming to the group uh you can you can certainly send in your nomination definitely yeah i'll think about it i know a lot of the uh the bondage folks i was just curious yeah they are they are everywhere over there right right on well uh nick thanks again for for having me and everybody thanks for tuning in hopefully hopefully you found this useful and picked up a new thing or two and but as always if you have questions find me on on twitter and uh happy to help absolutely okay everyone have a great uh weekend and a great night thanks all
Info
Channel: The Polyglot Developer
Views: 351
Rating: 5 out of 5
Keywords:
Id: yqXj7Jnqg9o
Channel Id: undefined
Length: 97min 37sec (5857 seconds)
Published: Sat Sep 11 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.