Build a Random Quote Machine with Nextjs, PlanetScale MySQL, & Drizzle ORM

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
today we'll be building this random quote generator app with next JS Planet scale serverless MySQL platform and drizzle orm for maximum type safety while working with our SQL database [Music] hello and welcome I'm Dave today we'll be using Planet scale's serverless MySQL drizzle orm and nexjs and I'll provide links to all resources in the description below I'll also provide a link for you to join my Discord server where you can discuss web development with other students and you can ask questions that I can answer and receive help from other viewers too I look forward to seeing you there we're starting today at planetscale.com and you can see their website says they're the world's most advanced serverless MySQL platform now this is not a sponsored video in any way but I did want to highlight using Planet scale because I've found it to be very cool and efficient so let's go ahead and click sign in now if we don't have an account at all you can just sign up for an account with GitHub it's just as simple as already having a GitHub login and signing in but if you do want to set up an email and password you can do that as well I'm just going to use or here is the actual sign up for an account and I believe yep there's continue with GitHub so that's what I was talking about I already have an account so I'm going to sign in and I'm just going to use GitHub as well and then I'll be in my dashboard and you can see I don't have any database set up here right now so that's what we're going to do now before we get started I want to say if you're not already familiar with SQL or an SQL database I've got a video on my Channel about that I'm going to link to that in the description and I'm also going to give a link to something Planet scale provides they have a nice little SQL course that you can work through as well and it's got some great fundamentals in there so I'll put both of those links in the description right now we want to go ahead and create a new database so that's what we're going to do come up with a name here I'm going to say quotes DB and click create database so we can see the database is initializing and I'll come back when this is finished okay the database has completed initializing and you can see now it says load balancer and it has the primary listed here we're in development as you also see on the page now we're going to go to the console for the database we're on Branch main as well and we just click connect and now we have a live console where we can issue SQL commands once again I'm going to highlight if you're not familiar with SQL you should be looking at those resources that I've provided in the description because everything I'm about to do won't make much sense if you don't know SQL already so we're going to need three tables for our database to power our random quote machine I want a table for authors a table for categories and then a table for quotes so let's go ahead and create the first table and that's for authors so I'm going to say create table and then I'll put lowercase authors as the name of the table a parentheses let me go down to the next line now and I'll just tab over just a little bit here and say ID and then it's going to be an integer and then it's going to be not null also Auto increment and then we'll make it a primary key after that we're also going to have an author and here this is going to be a varcar it's what I would say which is a variable character and it's going to allow 255 characters not in all and it will be unique because we don't want duplicate authors in our table after that enter one more time in a parenthesis and always in this console we need to end with a semicolon or it won't think we have completed the commands here so we're just creating a table with two columns we have an ID and an author column so I'm going to press enter and it should complete yes it did very quickly and we now have an authors table now I'm going to add the commands here rather quickly for the category table because it's identical to what we had above I'm just calling this categories and then notice we have a category column here so I'm going going to enter this as well and now we have our categories table jumping back to the browser and the planet scale documentation quickly I just wanted to highlight before we go ahead and create the quotes table the planet scale does not support foreign key constraints and we were going to have foreign keys if we set up a traditional mySQL database because the author ID that we list in the quotes table would be a foreign key from that author table that would have the ID and the same for categories so we would have two foreign keys in our quotes table traditionally but what we do have with Planet scale is the use of relationships as shown in the example above so just highlight here that they have a categories table in this example and then they have a products table and now here they're saying this key they're creating an index category ID idx which is just an abbreviation for index and then saying category ID that is right here so that's how they're handling kind of the foreign key relationship and it relates back to the ID in categories so we're going to do the same thing as we create the quotes table back in the console for our quotes DB I'm going to put in the command to create the quotes table now let's break this down we have an ID that is just like the ID column we had in each of these other tables then we have the quote itself which is just like the other information that either the author or the category from those tables and then we have a couple of other things here we have the author ID and the category ID and we're handling these because these would be foreign Keys just like they show in the docs here where we say key we create an author ID index and we pass in author ID the same for the category ID index and that's how we're going to relate these back to these other tables so now I'll press enter and we've created all three tables for our quotes DB so now we can just type show tables and I want to use all caps so you usually do and then we're going to show all three tables now we don't have any data in those tables yet but at least we can see we have indeed created all three tables now let's quickly put some data into our database and the tables that are associated with it so I'm going to say insert into authors and then we're going to insert into that author column because our ID will automatically be added it will be Auto incremented as we add more data and we'll say values and the value we're going to pass here our first author of a quote will be Neil the grass Tyson and now put the semicolon so it knows we're finished and press enter and it inserted that record so now we should be able to select that data and say select all from authors and we get our table back that has the ID and the author so there is our authors table currently so now I'm going to put in a similar command to insert some data here for categories I'm creating the Knowledge Learning category and I'll enter that and it's now inserted that data we could select everything from categories as well so you could do the same as we did from authors if you want to see that I'm going to go ahead and insert a quote as well and those IDs of course need to relate back to the authors and the categories tables so we're going to say author ID of one and category ID of one as we put in these values so let's take a quick look we're putting in the quote the author ID and the category ID so we have our quote and then we have one for the author ID and one for the category ID and now we've inserted that as well now go ahead and run select statements on these tables after you insert data just to confirm you've inserted the data now I'm going to go ahead and insert about four more quotes and authors and then I'll come back just so we have a little more data to work with in this tutorial I'm back and I've inserted the extra quotes and authors and even one more category so now let's just do a select all from quotes and we should be able to see all of our quotes here in the table so there's our quotes and this is how they relate to the authors and how they relate to the categories so in our app our next JS app we will be using drizzle orm to go ahead and query this data but right now we can write a traditional SQL query that we will replicate with Drizzle to select the data we want and it's going to have a couple of inner joins because we have these three tables and we won't want all the data from the tables we just want the actual quote author and category so let's go ahead and write this query that we would use to get the data we want in the application so here I'm going to say say select all from a DOT author C dot category and Q dot quote and I'll come down to the next line and say from quotes and that table will be referred to as Q as we've already seen then I'll say enter join and we're going to join authors and this would be a on Q Dot author underscore ID equals a DOT ID now we'll have a similar inner join here for categories which was C on and this would be Q Dot sorry I'm getting my caps mixed up Q dot category underscore ID equals c dot ID now that should be the full query to give us what we want so let's go ahead and press enter and see what our output is this is what we want to work with so we're going to get the author back and the category and the quote and this would be the actual quote record that we would want to work with in the application and we have five of those to go ahead and work with today especially if you like the dude from The Big Lebowski now we're still in development mode here so let's go back up to the top well we're in a different frame here remember we have the console frame here and then on the outside we have the outer frame here so we could come to the console or back to our overview and we want to go back to the overview here now click the gear over here by development we're ready to promote our Branch to production so I'm going to click promote branch and now I want to go ahead and click here again I believe let me check that yes we want to toggle enable safe migrations and then click enable safe migrations as well and now if we scroll down just a little bit we see this button that says get connection strings and we are going to need this so let's go ahead and click this we can open it up now and then just find what we want in a little bit oh we need a password to go along with the rest so we have create a name or it says create a password and here it has name this is on Branch main we are and admin so I guess this would be our password that it's asking for so I'm going to go ahead and Ctrl C to copy this over into just a text file somewhere on my computer so I don't lose it and I'll go ahead and click create password to see if that's what it does says it created the password and it actually it looks like that was a password identifier because here is what we need to access our application and of course I'm going to delete this database later so no point in using mine but this is showing how you will get yours as well which should be different than mine now right now this is showing how to connect with node.js we will need this later as well and we can come back to this when we do need it right now I'm interested in going to the at Planet scale slash database we're going to use these so if you want to go ahead and copy these and save them in a text file as well you can do that or we can come back and get them as we need to add them to our DOT env.local file in the next JS application so I'm going to go ahead and copy them right now so I don't necessarily have to come back and so we've got our database host database username database password all three of these you will need and if you ever needed to change your password the new password button is up here as well but now that we have that we are good to go so let's go to vs code and create our next JS application I'm in vs code and I have a terminal window open I am ready to create my project inside my next folder already so here I'm going to say npx create Dash next Dash app and I am going to use the latest however if you're following this tutorial at a later time make sure to check my package Json file to see which version I'm using because next JS changes things frequently and if you want to follow along and not have any errors possibly or just know that you're using the same version I am it's going to be best that you check my package Json and we can look at that here after it creates the application as well just so I can announce which version I'm using today so it says I need to install the following packages and it's going to be 13.4.6 today I don't even need to look at the package it's going to tell me right there so just press enter to say yes do that and so let's call this our quotes DB project and I'll press enter yes for typescript yes for eslint yes for Tailwind yes for the source directory yes for the app router no need to customize the default import Alias we will be using import Alias but I don't need to customize it so now it's going to go ahead and create the new next JS project and now vs code has completed creating the project and I've gone ahead and opened the quotes DB folder that it created now so I'm inside that folder and we need to create a DOT env.local file so let's just do that and I'll highlight something here in the root like the TS config then create a new file which is dot EnV dot local now let's paste in those environment variables that we got from planet scale so we have our database host our database username and database password I'll press alt Z just so we can see everything there we want to make sure we have all three of these values in that dot env.local now as I mentioned let me go to the package.json file and we can confirm that I am using next JS 13.4.6 today so if you want to install the exact version that I have you could go ahead and create the next app at latest if you want to and then just come back and go npm I and then of course you'd want to say next at 13.4.6 to match what I have and now we're back in the browser and we're at drizzle orm which is actually orm.drizzle.team and they've got a pretty good sense of humor if you look at some of the things on the website especially if you scroll down here to the reviews under developers love drizzle or I am I got a kick out of that check those out so after that it's explaining what it is up here at the top but an orm let's talk about that first if you're not familiar that's an object relational mapping and it's a way to align programming code with database structures so we're not going to write just our traditional SQL language inside of our code we're going to use this orm and this one really emphasizes typescript which is great it adds what they say is maximum type safety in mind as they created or maximum type safety to our code so let's go ahead and go to the documentation and see how we can get started with Drizzle now this is for postgres this first example they're giving us here so that's not necessarily what we want because we're going to use Planet scale under MySQL today so let's go ahead and click that and now we see what we need to install here it looks like we're going to install drizzle-orm then we're going to go ahead and install that planet scale slash data database a JavaScript client that it has and then under a development dependency which is what the dash capital D is we're going to install drizzle kit also so you can click the copy code over here now let's go back to vs code back in vs code we need to open a terminal window and then I'm in Windows so the things I have copied I can just right click and it pasted in and it starts running the installation here for drizzle orm and the planet scale slash database client but then we're going to have one other line to install here which is npmi Dash capital D for development drizzle kit and I need to go ahead and press enter on that and it will install that as well now there's one other development dependency we're going to need today and I'm only going to use it in development so I'm going to just install it while we're here so I'll say npmi and then it is dot EnV and then I'll put Dash capital D once again to make it a development dependency so let's quickly install this that's fast we'll close this and now let's look at our package Json so we have the drizzle orm here we have the planet scale database up here at the top and under Dev dependencies we have dot EnV and drizzle kit we are back in our planet scale here where we were getting our information and we need to get that node.js connection string now as well so from this drop down menu instead of the planet scale slash database let's choose node.js and now let's go ahead and click the copy here as well we'll go back to vs code and make this an environment variable in our environment variable file as well and back in vs code let's go to that dot ENB dot local and now underneath this I'm going to paste in the new environment variable notice it says database underscore URL so we want to make sure that's what we reference in our code when we use it now we need to create a config file for drizzle so again at this root level let's create a new file it's going to be drizzle dot config.ts the name is important because this is what drizzle defaults to if you don't pass the name of the file so it's best to just name it this drizzle.config.ts now let's go ahead and create this file first we're going to import type and this type is config and that is going to come from drizzle dash kit there we go after that one we're going to import dot EnV from dot EnV and then we're going to say dot EnV dot config and now we're going to pass a configuration here and I'm going to say path because we're not just using the dot EnV file we're using dot EnV dot local so we're just telling dot EnV specifically where the file is that has the environment variables now we'll say whoops I've did not mean to bring that parentheses down now we'll come down after that and we'll say export default put our curly brace now we'll say where the schema is going to be and this is going to be in dot slash source and then we'll say DB we'll make a DB folder shortly after this and then any file inside that DB folder could be a schema file after that let's say out and here we'll say it will be dot slash drizzle so it will create a drizzle folder when we use that and now we need our connection string this is going to be process.env Dot database underscore URL and then at the very end of this we want to say satisfies and fig and now we should have appeased typescript as well and I'm telling you how you could read multiple schemas from the same file but we're only going to have one today this means any file in that DB folder we're just going to have one and I'm going to name it schema.ts so you can specify just one as well we could easily create one file for each table we've got three tables but they'll all be in one file today so I'll just leave it specifically to that one file I may want to put something else in that same DB folder for example so I'll specify what it is you could also provide an array if I remember correctly and then specify each file path as a string for each schema also now let's go ahead and create that DB directory inside of our source directory so now I'll go ahead and create that there and we will add the schema soon but actually drizzle is going to generate it for us so let's go to our package Json and we can set up an introspect process and that means drizzle will go ahead and look at our database at Planet scale so it will connect to it with the values we've provided and then it will introspect and get information about that database and actually create the types for us which is pretty cool so here in the package Json let's add our introspect line under scripts I'll say introspect and now for the command we're going to say drizzle dash kit and then introspect colon we'll say MySQL now that said the output as we put in our config will go into this new drizzle folder this drizzle directory that it will create so let's open up the terminal and then we can say npm run introspect and it should run this process as it connects to our database it did it fast too so it said three tables fetched eight columns fetched five indexes zero four in keys because Planet scale remember doesn't really support foreign Keys it supports relationships then it created an SQL migration file and it created a schema for us the schema.ts that it's inside the drezel folder so let's scroll up and look at our new drizzle folder and see what's inside you also see this meta directory where you'll find a couple of things a Json file and a possibly another Json file let's take a look at that as well close this yes a small one here that's a journal so I think it journals every time you run that after that let's look at this one and yes it's got a lot of details in here about our database that's just the snapshot so now what we're interested in is here's the SQL file notice it's all commented out so we don't need to run this this matches what we already have but if you were to issue all of the commands this is how you would recreate your database and it's cool that it just generated that for us likewise here's our schema in the schema.ts now I said I'm going to put this in that DB directory we created but notice it's got the full amount right here I'll say alt Z just to wrap this down it's imported a few things maybe by default that we're not using I can see but overall this is pretty cool because it just created everything for us and this really shows us how drizzle works it likes to chain these different things but it's applying the same things that you saw we applied with our traditional SQL as we used the planet scale console so here is the quotes table schema here's the category schema and you can see the unique index here as well and here is the author schema so what I'm going to do is just Ctrl a to copy all of this and it will control a to select Ctrl C to copy and then I will scroll down to this database directory and I'll create a new file here that is named the same schema dot TS and then control V to just paste it all in now we just used introspect drizzle is also capable of migrations so say you would make a change to your schema then you wanted to send that back to the database and have those changes take place you can do all of that with Drizzle as well and I'm not doing that today but you could dive into the docs and check that out because it's not much more difficult than what you just saw me do with introspect and drizzle will also let you infer types from your model so this our schema or model whichever you want to call it really but it's our schema you could infer from that and it's called I said model because what it's called that you import from drizzle is called infer model to get your type but we don't want the type of any specific schema because remember our quote is going to use joins we're going going to get specific data from each table I said our quote I meant our query that we're going to use is really going to pull the quote out of this table it's going to pull the category out of this table and the author out of this table so it's it's that joined data so we're going to need to create our own type for that and to do that let's go down here to the root area once again and create a types.d.ts file and now let's create a simple type that is called quote and it's going to equal this object over here that has a quote that is a string and it's going to have an author that is a string and it's going to have a category that is a string and that will be our main type for the data we expect to get back now back in our source directory we need to create another directory and we can call it lib for library and it's going to create or contain some Library functions and we're going to create two rest API endpoints today as well as our front end that displays a random quote each time and we want to use these Library functions for both so we can get data when we are using a server component in xjs or we can get data of course once again the code for the routes that we would use for that API are also in the server so we can get data from either one of those so there's no reason to create two different functions that are identical let's just create one Library function and use it in both places so let's create our first function here inside our lib directory I'm going to call it get all quotes dot TS now I need to import connect and this is going to come from at Planet scale database there we go after that we also need to import config and that's going to come from are at BB and then we have our schema that's where our config is but we don't have that config file yet that's right I need to create that so let's quickly add this config file here as well and then we'll come back to this function so here I'm going to create a new file name it config.ts this is a very simple file and it uses our other environment variables so we'll just say export const config then inside of this we'll say host and this will be process.env Dot database underscore host now I'm just going to do shift alt in the down arrow to copy that down twice and we'll change what we need to change here so instead of host now I'm going to press well I highlight the first host then Ctrl D to select the second and because of an extension I have it's going to honor these caps and lowercase when I type so here I can just say username and this one stays lowercase and this one stays uppercase that extension I have a YouTube short on it is called multi-case cursor preserve if I remember correctly search for that and if it's not the accurate name it's going to be very close but I believe it is multi-case cursor preserve that allows you to select one then I press Ctrl D to select the next one and I can type password and it keeps this one lowercase and this one uppercase just as they were so you can see it preserves the case and that's all there is to the config file so now let's go back to our get all quotes Library function and I just noticed I typed schema up here this should be from config and then it's going to be okay after that we're going to need to import just a few more things so we're going to import drizzle this comes from the drizzle orm slash Planet scale serverless and then we're going to need to import the schemas we created so quotes authors and categories are all going to be imported from at slash DB slash and now this comes from schema there we go and now one more we need to import the equal EQ which means equal function from drizzle orm and we just stop there so not like the drizzle orm slash Planet scale serverless we had above with all of the Imports complete let's just type RFC I'm using my react uh es7 Snippets here press Tab and I get export default I need to add here async function which is going to be get all quotes and now that we have the quote type we created in our types.d.ts file I can say this is going to return a promise it's going to be an array of quotes because we're getting all the quotes and of course this return is not accurate at all we will not be returning any jsx here so to connect to the database we say const con to Define our connection and we use connect and we pass in the config we imported after that we'll say const DB for database we'll set this equal to drizzle and there we pass in our connection now let's query the database with Drizzle so I can Define the results and we expect the results to be an array of quotes when set this equal to await DB dot select but now we're not just going to use a select I mean if we just wanted to get everything from the table we wouldn't pass anything into the select but we need to specify what we want so we want a quote and that's going to come from the quotes table and the quote column an author is going to come from the authors table the author column and you might guess the same for the categories table and the category columns so we're being very specific what we want to get back from this query of the database the select statement so now we need to join these tables as we would with an SQL query so here I'll say dot from and it's going to be from the quotes table then we can say dot inner join and we'll say the authors table here's where we use that EQ function we imported and we say quotes dot author ID and then needs to be equal to authors dot ID and now this will be very similar for categories so we'll also say dot inner join here I have categories once again equal to quotes Dot category ID and this would be categories dot ID that would be our full query that would be equal to what we used earlier inside of the console of Planet scale to get those results where we had the quote author name and category name and now you can see typescript is telling us all we're missing is really the return value so let's just return the results now there's our library function we'll be able to use this for a route TS file that we would use for the rest API endpoint but then we'll also go ahead and use it in our own application the front end of our next JS application where we can get this data from the planet scale database and present our randomly changing quote on the home page and I say that but this is actually the one we're only going to use in the rest API because it's returning all quotes now let's go ahead and create our get random quote Library function as well so we can do that with a new file and say get random what dot TS okay we're in the new file but let's go back to our get all quotes here and it looks like I need to save this but also we want all of the same Imports that we're using in get all quotes to be in the get random quotes file as well so I'll just copy all of those now paste them here inside of the get random quote dot TS file notice we had get all quotes plural but this is get random quote singular now let's come down once again use react es7 Snippets here try that again press Tab and now we have our get random quote function and much like the predecessor it's a promise but this will just be a quote not an array of quotes because it's once again singular we can get rid of the return let's jump back to our get all quotes once again because this is going to be very similar to what we were doing before so we'll connect once again connect the same and we'll actually run the same query to get all of the quotes because we'll have all of those before we randomly decide which one to return so now let's go back to the get random quote and we'll once again make that same request here with Drizzle and we can see we need to make this an async function also and so all of that code is the same but now we need to make just a few changes and one of those things is to actually keep track of some State outside of the function and that's because it would be possible to press the refresh quote button and randomly get the same quote again and we really don't want that to happen so we can keep track of something outside of the function so in that regard the lexical scope essentially we can say hey don't return the quote if it's the same one we had before so to do that I'm going to say const I'm going to call this the previous quote object we're going to set this equal to an object here and I'm essentially going to set up some State like we would with use state but it's essentially out of the function so I'm just going to say previous I'm going to set that equal to 1 and I'm going to have a set previous function which is a function it's going to receive a number and now after that inside of the function we'll just say this dot previous equals that number so that will set the previous value now let's scroll down inside of our function here and of course we need just a little bit extra room after our query and yep that looks good so let's go ahead and put something over here that will help us determine that random number so I'll say let random index is what we'll call this variable I'm just going to set it equal to the previous quote object dot previous of course because that's the value and now let's set up a while loop and this will just say while random index is equal and we'll do a strict equals to previous quote object dot previous we'll keep looping through because we don't want it to be equal to whatever the previous Choice was and now inside the loop we'll set the random index equal to math.floor and we'll call math Dot random and we'll take that times the result not results is it just result or results let me double check that it's results so results dot length so this should select a random number we just don't want that same random index of the array to be what it was before and if it is equal to that it's going to keep looping through so it doesn't proceed further and deliver that same quote again let me move this curly brace over there we go that looks better and now all we need to do after the loop is complete because the index number is not the same we'll just say previous quote object dot set previous so we know what it is next time the random index remember all of this code's running on the server and we'll say return result and we'll just pass in this random Index right there so that would be a random quote I said result once again it's results there we go results random index which would give us one quote so if we Mouse over this we can see it's an array of quotes but now we're passing in that one index just to get that one specific quote from that array and that should complete our second Library function so now we can get the random quote and we can get all quotes and the get random quote is the one we'll use on our front end with the library functions complete let's scroll up to the app directory and inside the app directory we want to create an API directory now inside the API directory we're going to create a directory for each of our routes that we're going to have so let's create one here called quotes that will return all the quotes So inside this directory we're going to have a route dot TS file now we're going to import and we'll have next response from next server and after that import we're also going to import our get all quotes function that we just created inside of the library directory now let's say export async function and it's going to be a get request or a git endpoint here and then we'll have the request and after that this will be very simple we'll just say const quotes equals a weight get all quotes now we should have all the quotes so we'll say return next response dot Json and we'll pass those quotes in that is our complete endpoint here for this API this should return all of the quotes now the next one we create is going to be almost identical so I will control a to copy all the code control C I guess control a to select control C to copy now with the API directory once again I'm going to create another directory inside of it I'm going to name this directory random we don't even need the dash I'll just call it random quote all one word and now inside of this directory I'll put another route.ts file I'll paste in the code that we just had but instead of get all quotes we're going to import it random quote from our at lib get random quote file there we go so just changing a couple of things on the import likewise we're going to use that same function down here and we should be able to get a random quote and we could just call this quote even though we wouldn't have to change it but that makes more sense and we can save that now we've completed both endpoints and we're ready to try them out I'm going to use the ThunderClan extension as it's built right into vs code and you can see the logo over here search for thunderclient and extensions if you want to use what I'm using but you could also use Postman or several other extensions that do the same thing so I'm going to have a get request and I believe I've basically already created it before and so here I'm looking at localhost 3000 which would be our application API quotes now what I haven't done yet I'm just thinking about this is actually start our next JS application so let's type npm run Dev to make sure it gets up and running and is ready to receive requests okay so it says it's running now on localhost 3000 that's good close the terminal window this is going to hit that quotes endpoint and we should get all of the quotes back along with their authors and categories let's give it a try I'll click Send processing let's see what we get back and here are the results so I will scroll this up we have an array of quotes and it looks like everything we wanted remember this didn't come from our local environment this went out and connected to Planet scale already and brought it back so we know everything is connecting and working like it should we've got our drizzle orm in there connecting to Planet scale it's all good we're getting the data we want now let's change this quotes endpoint to our random quote endpoint and let's send once again and we just get one quote back notice it's not an array it's just an object with the one quote let's send it again to see if we get a different one yep different quote different quote so everything is working as we expect it to with the API routes working already we know everything we've implemented is working our functions with Drizzle and Planet scale so basically what's left is creating the front end and you may or may not be interested in that it's got just a little bit of Tailwind in there let's go ahead and make those changes and I'll do it fairly quickly as well let's first let's go to the layout.tsx that's just inside of the app folder along with the main page here I'm just going to change this metadata so I've highlighted everything that was there and you can see I've changed it now to random quote machine this page generates a random quote is the description now we're going to change what we're returning here which is basically HTML and the body we want to go ahead and add just a little bit more to that and wrap it around the children so let's go ahead and do that and all I'm going to do is add an extra main element here inside of the body that wraps around the children and it's got a few Tailwind classes applied to it I can go ahead and press alt Z and remember I will be linking to all of the source code in the description as well so you could grab all of this there if you want but there are the class names that I'm applying to the main element inside of this layout component now let's go to the page TSX that is right beside it now the default page of course comes with a lot of information so really I'm just going to select all of that with Ctrl a hit backspace get rid of everything there paste in my very simple page now we haven't created the quote component yet you can see I'm going to keep it in components and slash quote but this is the home page this is the server page now the quote component itself is going to be a client page so the user can refresh the page whenever they want to that's of course it has some interaction right there that they're taking so we're going to make that a client component but the rest of this you get random quotes this is going to be servers side rendered so it's issuing this request from the server which is also a good discussion here because we did create API routes but you don't want to set up your server component to request from your API route in the same next app because whatever data the server component requests needs to be available at build time and it can't be available if you're also building your route so I just wanted to highlight that I've been asked that a few different times you could request from an API route in your client component but not your server component that will cause a build error let's once again create a directory inside of the app directory now and we'll call this components imagine the app might have more in the future we're just going to create one here and it is going to be a file called quote.tsx as I mentioned this will be a client component so we need to use client directive at the top then I'm going to add some code here and if you haven't seen this before you possibly have if you've worked with nexjs because you usually see it in the default layout I'll come back to this real quickly because they have this enter font right here from next slash font slash Google some of them of course enter isn't one it doesn't require that much for configuration but I'm using a couple of fonts here that just have a little bit more configuration so I've got Roboto and Poppins and you can see I've imported them both above so I'm just using two different Google fonts here now I'm going to scroll for a little room and we're going to need a couple of hooks as well so I'm importing use router from next slash navigation and use state from react now let's go ahead and create the quote function I'll type RFC again with my es7 react Snippets says export default function and it's got quotes so that is what we need of course the return will be different so I'll go ahead and delete that now this is going to receive the random quotes so we need to put that right here random quote and it is a type quote that we previously created let's go ahead and initialize those hooks so we can see we're defining router with use router and then we've got a fade and set Fade with use State initially set to false now this is just for that CSS fade in Fade Out that you saw at the beginning of the video when we're getting those random quotes it essentially helps me switch the Tailwind classes let's scroll for a little bit of room but underneath these hooks I'm going to go ahead and start the return but the parentheses here and we're going to have a section that wraps around everything so let me alt Z so we can see all of that at once and I need to put in the closing section here you can see it's got several Tailwind classes on it and here's where I'm using the fade from the use state so essentially if it's true we're setting the opacity to zero and if it's false we're setting it to 100 and a lot of this does the animation here as well so we've got the transition opacity ease in out the duration is one second the duration is going to be important so you get that little bit of darkness and you'll see how I apply the rest of that with the on click in the button here in just a second this section is wrapped around everything now we're going to have two different divs inside of this section one for the big quote and one for the button and where we have the author in the category so putting in the author and the category first this is going to appear to be a lot but we can go over this quickly because it's not that bad and if I save we'll get a little formatting so now we have a div here inside of the section it's our first div and the first thing we have is a button now here's how the timing works on that animation so the duration on the Fade Out is one second and we set the fade to True when we click so it begins to fade out for one second basically at the same time that Fade Out is over we call router refresh from next JS and that refreshes the page now when that happens we've already got it set to True here so what's going to happen then or we don't refresh the full page essentially we're refreshing that data but what next JS router refresh does because we're still using use State and now use State comes back and sets itself to false just 200 milliseconds essentially after this set timeout because if they were both a thousand they'd be equal and so we just need that little space of time where we have a dark screen before it fades back in So milliseconds they look big when you say a thousand and twelve hundred but it's actually really fast so that's the refresh quote button here in the on click and of course you can once again see the different Tailwind classes then down below we have the author and the category as well and I could separate those so you could see both and that's all inside the first div then we're going to have the big quote here in the next div and in comparison the big quote looks fairly simple it is set to grow as we have a flex box and we want the big quote to take up most of the page so it fills out the rest of that page and you can see it's much larger with the text Dash 5xl class name here and it's using the Roboto text but overall that is the full quote page and so this all pulls it together and besides the logic kind of in that fade not much new there but we're using that same data we're just passing in the random quote that we get from the parent server component that is an SSR a server side rendered and essentially just passes it into that quote component that we have there so if we come back to the page here's the SSR that I'm talking about and we pass that random quote in let's go ahead and save this page and I think we can open up the terminal and confirm that this is still running so now let's open up localhost 3000 and check out our application so there it is I'm going to control click open that in the browser and let's check out our app there's our first quote let's see if the button's working and we get a new one yep there's our next quote so everything is working as expected I hope this app and creating this project a short little one helps you understand how you can quickly create a mySQL database on the serverless planet scale that's pretty cool and it's very fast we're getting this data back very quickly remember that's not in our Dev environment it's reaching out to Planet scale and then it introduced drizzle orm which by the way isn't even on version one yet it's in the very early stages but it's already pretty good so you might want to play around with that as well and then once again just another next JS project to get you a little more familiar with how you might want to do things inside of next JS when working with an orm and a database remember to keep striving for Progress over Perfection and a little progress every day will go a very long way please give this video a like if it's helped you and thank you for watching and subscribing you're helping my channel grow have a great day and let's write more code together very soon thank you
Info
Channel: Dave Gray
Views: 23,476
Rating: undefined out of 5
Keywords: build a random quote machine, random quote machine, random quote generator, nextjs, next.js, next.js 13, nextjs 13, planetscale, planetscale mysql, mysql, drizzle orm, drizzle, drizzle-kit, sql drizzle, sql drizzle orm, sql, mysql planetscale, planetscale drizzle, drizzle planetscale, drizzle orm planetscale, drizzle orm sql, drizzle introspect, drizzle schema, nextjs app router, next.js app router, nextjs project, next.js project, nextjs database, tutorial, js, javascript
Id: d7XJjQesDtE
Channel Id: undefined
Length: 50min 53sec (3053 seconds)
Published: Sun Jun 18 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.