Remix Crash Course | Fullstack React

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] hey what's going on guys welcome to my remix crash course so in this video we're going to learn all about remix while building a blog application also using prisma and sqlite for a database so before we jump into the code i just want to talk about what remix is and why it's beneficial so remix is a new framework it has a lot of hype it was created by the same creators of react router in fact it's basically built on top of react router and the good news is it's not just a new framework with no purpose other than to just create another framework it's for react developers and it's a full stack framework that solves a lot of problems that single page applications or purely client-side apps have now we do have next js which also offers rendering react on the server next.js is a fantastic framework i use it a lot i have a course on it and i don't think it's going anywhere i do think remix feels a bit different in the way that it does things particularly using what are called loaders and actions which we'll get into in a little bit but i'm not going to compare the two i'm not going to say one is better than the other but i do think that we're moving away from the single page application and moving more towards building with next js remix next for vue and you know full stack frameworks like this or you should say server rendered applications so as far as some of the benefits of course server side rendering is huge it has some great benefits especially with seo file system routing is also great you don't have to explicitly define all your routes you just create a file and put it in a certain folder and it just works as a route similar to how old school i shouldn't say old school but how php sites work you also have nested routes with remix which is pretty cool we can use the outlet element from the react router and build a hierarchy of routes these nested routes are server rendered and it's almost like a hybrid of a single page application and a server side rendered application now loaders and actions i think really make learning remix worth it you get a lot of control when it comes to dealing with the request and response loaders are basically functions that you can put directly into your route modules and they run on the server side and if you need to fetch some data and load it into your page you can do it from there in our case we'll be using prisma which is an orm to get data from an sqli database and we'll be able to put it right into our route loader or right into our page actions are also something that caught my eye and if you guys have worked with php before you know that when you submit an html form you can you can make a post request with a form without javascript without having to add an onsubmit handler and remix allows us to do that by using something called action functions so we can actually make requests directly from html without javascript using these action functions and we'll get into that you know in a little while so you can also have easy access to head tags from any route module if you want to add a meta tag like let's say keywords or description on any of your pages or any of your routes you can do that really easily same thing with links if you want a specific css file in our css link in the head you can do that really easily with remix error handling is also included and really easy to use you can export an error boundary component inside your route module which will basically handle any error for that specific route and you can also create a root error boundary you also get typescript right out of the box you can generate your your boilerplate app with typescript and tsx files or you can do it with javascript and you can pick and choose which files you just want to change to typescript all you have to do is change the extension we also have built-in support for cookies and sessions which is really cool there's a function that remix provides called create cookie remix has built-in support to work with sessions using cookies the file system server memory or custom storage so these are all really cool features that remix offers so my plan is to get a remix app up and running and talk about what it offers and show you how loaders and actions and nested routes work but also build a blog application at the same time where we can use prisma which is an orm and also use sqlite as our database which you could easily switch out for postgres or something else so we'll get some basic functionality done today and then probably in my next video i want to add user authentication so people can come and they can register sign in create posts and delete their own posts we can get into cookies and sessions and all that all right so let's go ahead and get started all right guys so we're going to get started and i would suggest that you follow along and code along with me i think that's the best way to learn and to retain information but of course it's up to you so this is the documentation and you can see we can get started with npx create remix and they're telling us to use at latest and you can do that or you can use the the version that i'm using which is the latest at this point is 1.0.6 so you can either use latest or you can use the the version that i'm using so i'm going to go ahead and run npx create dash remix at latest and it's going to ask us some questions the first being where we want to put this i'm going to have a folder called remix blog and then where do you want to deploy so you have some options here like fly dot io versel netlify i'm just going to choose the remix app server and then you have the option to use typescript if you want which i probably would if i was in production but since it's a tutorial and some people might not know anything about typescript i'm going to go ahead and choose javascript and yes i want to run npm install okay so that's all set let's cd into remix blog and i'm going to open up visual studio code from here and of course you can use whatever whatever text editor you want so we have the files and folders i'm going to go over in a second but let's run the dev server first so if we open up uh integrated terminal i'm going to run npm run dev that's the command to run this on localhost 3000 and then you should get something like this it's just a simple demo so if we go to like actions it has a form where you can submit to an action function and we're going to get into all that but i want to basically just blow everything away all the demo stuff and start from scratch because i think that that's the best way to really learn what's going on here so let's go into the package.json and you'll see under dependencies we have react we have react dom and then we have remix and we also have this remix run react remix run serve and then the dev script that we just ran so npm run dev npm run build will build for production and it actually creates two build folders one in the root which is the server files and then one in public as well which is the client so the public folder you can use for static assets like images fonts etc but most of the stuff that we'll be doing is going to be in this app folder okay so this is our basically our application so let's go through some of this the the entry files here entry client entry server are really just that they're the entry points this one here entry dot client this is going to be the javascript the first javascript that's run when our app is ran in the browser and you can see we're using react-dom here and it basically hydrates our react components and then entry dot server uh this is going to be ran basically when we make our request to uh to the server remix handles the loading of the data and we're responsible for sending back a response and that's one of the reasons i really like remix is the amount of control that we get when it comes to the the whole request response cycle now the the routes folder this is going to be where our route modules go which are basically just react components functions and i'll get into how the the nested routing works and all that in a little bit styles so you we have a global css and you can also create style sheets for specific routes and then we have the root jsx which is basically our root app component and there's kind of a lot going on here so what i want to do and what i want you to do if you're following along is just to get rid of everything here in the root and save so this is going to give us an error it says route root has no component please add a default export in the route module file so we're going to go ahead and add an export we want to export as default a function called app and then in here i'm just going to return and this returns jsx it's just a react component if i put an h1 in here and just say my app and we save that we come over here and reload we should see my app all right i'm just going to resize these so if i view the source of this all we see is a doctype and an h1 that's it there's no html head body tags nothing and we have complete access to to that root document so in this app function that's where we want to put that stuff so we want an html tag let's put a lang set that to en and i don't know why this didn't change too so html and then inside that we're going to want our head tags and then i'll just put a title tag in here we'll say my remix blog and then let's uh that's all i want in the head for now then we'll have our body now in the body we're going to have an outlet so the outlet is basically whatever route we're on whatever route module that's going to be output here now we do have to bring that in so let's go up here and let's say import outlet which is part of react router dom but remixes is actually built on top of react router dom so we're bringing this in from remix okay so if i go and save go ahead and save that we're now seeing the index page again which is in the the routes index file now before we get get into routes there's a couple other things i want to show you so one if we want to have live reload so if i go ahead and just type in hello here and then if i do hello one and save you'll see it's not it's not reloading automatically so we want to bring in live reload from remix and what we'll do is right under the outlet we'll have an expression and we'll say where the process dot env dot node env where the node environment is equal to development when that's true then we want to have our live reload else then we're just going to say no all right so now you'll see if i change that one to a two and save now it auto reloads if i get rid of it and save it goes away now instead of putting all the the document stuff here like the head body html and it's right inside the app component what we're going to do is have a function called document and that document is going to take in an object with children because we want to be able to wrap this document around something so it's going to take in children and we'll also pass in title and then what i'm going to do is take everything from within here and cut it and we want to then return we're going to return and then i'm going to paste that in here now instead of the outlet in the document we're going to put the the children okay because whatever we wrap this around we want that to output here all right and then up here we can simply put the document and then we want to have the outlet all right so if i save that we should get the same result and we could do for the title we could do something like if title then title else then my remix blog i don't know why i put my i'm going to change that okay so we'll save that good now the next thing i want to do is create a layout because we might want to have a we we will want to have a little bit of navigation on the page and i could put it up here like whatever i put in here is going to be on every route if i go to this route we're still going to see that hello so i could do it here but a nicer way to do this and what they had before i deleted it was a just a layout component that we could wrap around the outlet so let's do that let's create another function called layout which is going to take in children because we want to be able to wrap it around something and from here let's return i'm just going to return an empty fragment and then we'll have a nav with the class of navbar and you're going to want to copy these classes because i have a global style sheet that i'm going to be bringing in as well so in the nav bar i want to have the the the logo it's well it's just going to be text but i want to wrap it in a link and instead of using an a tag it's going to be an inner link so we actually want to use link from remix not from react router dom but from remix so i'm going to auto import that so now links being brought in so and it's used the same way we just add a two attribute this is just gonna go to slash and i'm also gonna give it a class name of logo and then here we'll say remix okay now we're not gonna see anything just yet because all we've done is is created the function but i just want to finish this up so in addition to the logo we're going to have ewell i'm going to give this a class of nav with a list item that's going to have a link to and that's going to be to slash posts and we'll say posts and then under the nav we'll just have a container class and that's where we want to put the children okay so whatever we wrap it around now we can come up here into our app and we can just wrap the outlet in the layout okay so we'll save that now we can see the the logo and the link which you know doesn't look too good because we have no css now i'm going to show you how we can add some styles but i just want to clear some things up first so in routes there's a folder called demos i'm going to completely delete that and then in styles i'm going to delete that demos the demos folder and then i'm also going to delete the dark css and in global css i have some styles i'm going to paste in and you can grab this from the the repository in the description so i'm just going to paste those in and we'll save and then let's go into the routes index j jsx here and i'm just going to clear all that up and we just want to create just a a basic function a react component that returns jsx and i'm using this extension here a lot of you guys probably use it this es7 react redux react native snippets and it just allows me to generate react components i like to use just a regular function with the export at the bottom which is rfce okay now i don't want to include i don't want to import react at the top because that's not it's no longer needed so with this component you can just add an underscore rfc enter and then it gives you the function without the import and i'm just going to call this home okay and then we'll just have an h1 in here and we'll just say welcome for now okay so now we just have the showing now the styles even though i put the global styles in they're not showing up because we haven't put them anywhere right so i want to show you if we go to the root jsx i want to bring in the global style sheets we'll say import let's say global styles url and we're going to import that from now we can actually use the tilde here that's just like the the root so we'll say all right not the root but the app folder so from there we want to go to uh where we go styles styles and then global.css so we're bringing the file in now what i could do since i'm in the the root here and i have access to the head tags i could just go ahead and put link in here and set the href to that global styles url if i save that you'll see that now the styles take effect however if i'm in another route module and i want to load another style sheet i won't be able to do it this way so what we can do let's get rid of that and what we can do is bring in from remix we can bring in links and we can put that links element in the head so i'm going to put it right above the title links and then all we have to do from any route module we can just export a new function called links i'm going to use an arrow function and all this has to return is an array with an object that has a rel in this case we want this to be stylesheet and then just an href and we can set that to our global styles url if i save that now you can see that styles the styles take effect so i could put this in any component loading any style sheet and then similar to that we can do the same with meta tags so in some cases you'll have meta tags where you're going to want the same ones on every page so for example i'll paste in the character set and the viewport but like keywords and description you're going to want that to be different on you know in every route so we can bring in meta which works in a similar way i'm going to put this right here we'll just say meta and then in any route module we can create or export a function called meta and what we want that to do is return an object with whatever meta tag we want we could say description and then we can set it here or i'm just gonna create a variable up here so description and we'll set it to we'll say a cool blog built with remix and then we could do keywords so cons keywords oops and set that to we'll just say remix react javascript doesn't matter and then we'll add keywords to the return here okay and then that should do it so i'll save uh keywords is not defined i don't know what is up with my typing okay now if i look in the um the source code for this if we check this out we have the viewport and and and uh was the other one the character set and then we also have the description right here you can see the description and the keywords so any any meta tags you want to set on other pages you can do here which obviously is good for just seo so now we're going to start to look at routing so i'm going to close up the root file for now and right now we just have the routes folder with this one index.js and this file isn't going to do much it's just the home page so i'm just gonna have an h1 in paragraph in here you guys can put whatever you want on this but let's go ahead and create in routes a file called posts dot jsx okay now the routes these route modules are just basically component functions so we're going to just generate a function here and i'm going to call this posts and for now let's just put an h1 we'll say this is the post route and then i'm just going to go to slash post we already have a link here and it just works so similar to like how next js works it's just it's it's file system based routing so you don't have to go and manually create your routes with react router dom although you can do that because that's included with remix you can explicitly set your routes or you can just put put pages right in and they just work now you do also have nested routing which is pretty cool so in the routes folder i'm going to create another folder called posts so i'm matching the name of this this post file here and then i can nest routes within this file so i do that with the outlet from well from remix but also from react router dom so let's import the outlet from remix and then down here under the h1 i'm gonna put the outlet okay so now if i create in my post folder let's create a file called new.jsx and let's just create a function here we'll call it new post and then we'll have an h1 in here and we'll say new post and i'll save that and then let's go over to the browser and let's go to post slash new and it shows the content that's in new post but it's still it still also shows the content that's in the main post file because i'm nesting this new route into this post route okay so anything i create in this post folder it'll show but it'll also show what's in the parent route which is pretty cool you could have like a post only navigation that you you only want to show on the post routes now in in our situation for this particular app we don't need to put anything else in the main on the parent posts so i'm just going to leave it as an outlet and we'll just use a fragment here but we'll keep it this way just so if you want to add something here you can and it will show on all posts now since i do want to have a just slash posts what we can do is in the post folder just create an index.js sorry index.jsx or tsx if you're using typescript and then we'll go ahead and create a function that didn't work for some reason and we'll create a function called let's call this we'll call it post items because that's what we're going to do here is list post items and then we'll have an h1 and we'll just say posts so now if we come over here and reload we're at slash posts we should just see posts and we also have the new post slash new and then there's one other route that i'm going to going to want to add and that's to show the single post now with that the url that i want is post slash and then whatever some kind of id like this and i'll we'll go over error handling in a bit too but it's going to be just some id so this is going to be dynamic so the way that we can handle that is by creating a new file in the post folder and we're going to use a money sign because this is basically like a dynamic like a variable route and then we want to call it whatever we want to name that param in this case it's going to be post id dot jsx so money sign post id jsx and then we're going to create a function and we'll just call this post and then down here we'll just say post actually make this an h1 and say post so now if i go to post slash and then whatever a bunch of numbers it shows me this this content now if i want to grab this which i'm going to want to later so we can get a single post from the database we can just use the use params hook okay which is the same as in with react router dom so use params i'm going to bring that in from remix and then we just above the return create params and set that to use params and then down here if i wanted to output that i could just do params dot and then post id and the reason it's post id is because that's what i call the name of the file that's what i call the param so now we'll get post slash whatever i put here if i put one we get post one alright so at least now we have our routes created they don't do much but we haven't created and now we're going to look at one of the coolest features about remix which are loaders so i'm going to go ahead and just keep open the the posts index so it's the po in the post folder the index.js and we want to use what's called a loader and and it's used to do that it's used to load data and that could be from a database like ultimately we're gonna do but it could also be from an api it could be anything really any anything that you want to load when the page loads so up here we want to import a hook called use loader data and that's going to be from remix all right so we have the hook and then to create a loader we just export a function called loader and then this has to return something so for now i'm just going to return an empty object and i just want to do a console log here i'll just console.log one two three and you'll notice that it logs down here and the reason for that it doesn't log in the browser console it logs here because loader runs on the server okay so you can do your server-side stuff right in this function and the idea is you you do your server stuff you get your data and then you can use this hook down here in your function to access it on the client so ultimately like i said we're going to use a database we're going to use prisma with sqlite but just for now i'm going to create uh just some hard-coded data so this will be an object and let's do posts with an array of objects that'll have an id we'll do an id a title say post one and we'll do a body for body we'll say this is a test post and then i'm just going to copy this down we'll do three of them and then we'll just change the titles here so this will be two three and then we'll change the id so 2 3 and then i'm just going to go ahead and return this data now like i said we access this data now with this use loader data hook so we come down here above the return and we can say const data set that to use loader data and now we'll come down actually we can destructure this we can just take the posts out of the data and then we should be able to take our posts map through them just like any react component so we'll say for each post we want to then let's render a list yeah let's wrap this actually in a ul we'll say ul will give us a class of post dash list because we do have some classes we can use to make this look decent and we'll take this and we'll put this in here okay and then we want to map through each one and render a list item and this has to have a unique key so the key will set to the post dot id and then in here we'll do uh let's have a link we need to bring that in from remix so the link will say two and for now we'll do post dot id and i'll put an h3 in here this will be the post dot title and then under that we'll have uh we're gonna have the date the created at but we don't have that yet because it's just dummy data so let's just save that as is and you can see we get our post one two three and the styling is just from the the global style sheet all right so i mean and right now obviously it's just hard coded data but it can be from a database later on we're gonna pull it from uh from a mysql not mysql and sqlite database using prisma so i just want to kind of format this a little better this h1 we're going to have a div up here with the class of page dash header and the div with this wrapping div we can just use a fragment and then i'm going to move this h1 in here and then underneath that we'll have a link and this is going to go to the new page so we'll say two slash post slash new and i'm also going to just give this a class name of btn and then here we'll say new post so we'll save that and then we have a nice little post page so loaders are pretty powerful because they they're they run server side so we can do a lot more right from you know the same file that we have our output in which is i think really valuable now there's also something called actions where usually you have a form say we have a react app or angular whatever you have a form you have an on submit function that actually stops the form from you know naturally submitting to a file in the browser to catch it and then do something in javascript well with remix we have something called actions where we can we can really submit the form so we're going to have a form we can actually submit it to the server without having to add an on click and we can just we can catch it in something called an action function so we're going to go to new jsx to this uh to this new post and let's first just build out the form it's not going to be too bad it's just two fields a title and a body so we'll go ahead and let's add a page header here so page header we're going to move this up here and then we're just going to have a back button or back link so i'm going to import this from remix and this is going to go to just slash posts and we'll give it a class name of btn and btn reverse and it's just going to say back so if we look at that now we just have this back button here and then down here under the page header let's create we'll say page dash content and this is where we're going to have our form now this action we could use this but since we're submitting to the same page we don't need the action but we also don't need an on submit in fact we need to make sure that we set the method here to post because we want to make a post request and this might if you know if you if you used to be a php developer like me this looks very you know it's very familiar so or if you are a php developer so let's create a form control class here and then we're going to have a label this is going to be for the title title and then underneath that we'll have an input and it's going to be type text and then we're going to use a name when's the last time you actually needed a name so name is going to be title because that's how we can access it in the action and then it's going to have let's do an id of title as well and then we're just going to have the body so i'll just uh we'll just copy this down and we'll change this to body and we'll say post body we'll change this and the title i mean the id to body actually you know what this i want this to be a text area so we'll say text area okay so if i save that we should see the two fields now we just need a button so let's do button we'll give it a class of btn and btn-block and yeah and here we'll just say add post and we'll just make sure we add a type here of submit because we want to make sure this submits the form okay now to you to create an action very simple just like a loader we just create a function an exported function so we want to do explore const and call it action all right and this has to return something so we're going to actually bring in redirect from remix so lots of little tools to help you here so we want to return redirect and we're going to redirect to let's just say slash posts okay now i just want to show you if i console.log here we'll do one two three again and then i come over here and i submit this form we should see down here in the server console you should see one two three all right so we're able to submit to the server and we can do whatever we want in here now action it should take in or an object with a request so that's the server request or the http request and the way that we get these fields so obviously we're going to need to get this data right from the form we simply create a form variable and we can set that to a weight because this is going to return a promise so we want to await request actually this should be asynchronous so async and then request dot form data and if you if we just want to see what that looks like we could console log it so if we submit that and then we look down here you'll see it's a remix form data object and it has these url search params with title and body now obviously we want each value so what we'll do is go up here we'll say const title uh we'll say title and the way that we can get that is with the get method so form dot get and we want to get the title and we'll do the same with the body all right and then um what we'll do is oops we'll create an object called fields and we'll have we'll say title body and then we'll just console.log here uh we'll console log those fields okay so now if we come over here and we submit and we add post if we look down here we should see right here an object with the title and the body all right so i mean all we have to do now we'll just put a i'll just put a to-do here and say submit to database and we'll do that in a little bit before we do i want to show you how we can handle errors because remix is actually really good with errors using the this error boundary so if we look right here in the docs it says remix sets a new precedent in error handling and it automatically catches most errors in your code so this is really helpful and it actually does a lot for us in terms of of throwing errors and and catching them and all we can all we have to do is add an error boundary we can do that within the route module we can also add a root error boundary so first i'll show you how we can do it here and let's let's throw an error on purpose so on the new on the form page here on the new dot jsx it has to return something so i'm just going to comment out the return and then submit and we get this weird cannot read property route of undefined in server.js like who knows what the hell that means so let's create down here at the bottom we'll create an error boundary so we can do that by actually want to go above the export and let's say export function error boundary okay and then this is going to take in an object with an error and from this we could console.log the error so we have it in the console but then we want to return what we want on the page so that's going to be in this case we'll just do a div and it's not working for that so a div and then we'll do an h1 and we'll say error and then underneath that we'll do uh we'll do a pre tag and then we'll have that error object has a message on it so we'll do error.message so that should work if we come back here and we try to submit again with that with nothing being returned now you see we get error you define an action for route but didn't return anything from your action actually let's put that in a paragraph yeah it's better okay so now we have a nice clear error message now like the documents documentation said you can have a root error boundary and you can have both but what i'm going to do is just take this out of there and put it into the root jsx so we'll open that up i'll go down to the bottom of that page and paste that in now if i try this again i just want to show you if i try this again it does show me the error but notice the the whole layout's gone because we're just from the root we just have a div and this and that what what we can do though is change this to our document and then have our layout around it all right so we'll just take this move that into our layout and now it should if we get an error now now we have the layout around it and that's going to work for all routes and of course you could put you could put the error boundary if you wanted to do something specific on a specific row because it's going to look for the closest error boundary all right so now that we've talked about actions and loaders and you know routes and all that i want to now get into the the database stuff so we're going to be using something called prisma and i'll just do a kind of a quick intro to that for those of you that have never used it so it's it's an orm or an object relational mapper and it's basically you can think of it as an abstract or a layer that sits over your database whether that's sql lite like we're going to use or postgres or whatever and it gives you an easy syntax to use to make queries to that database so it's it's like mongoose if you if you guys have used mongodb with mongoose it makes it easier you create your model and then you can do a syntax like this so this is just prisma dot and then whatever the table dot create in this case and then just pass in an object of data so really really nice syntax easy to use and if you want to switch from sqlite to something like postgres it you just change the config everything else stays the same so really really cool and goes really well with this type of with this type of framework so let's go ahead and install a couple things i'm going to close these files up and i'm gonna just stop this and we want to npm install prisma and then we also want the client so it's at prisma slash client so we want to get those installed then we want to go ahead and clear this up and run npx prisma and we want to run init and we want to provide a data source provider so we're going to say dash dash data source dash provider and like i said we're going to be using sqlite so we just want to do space and then sqlite and that should go ahead and create a schema so over here now in our file structure we have a folder called prisma and we have the schema.prisma file so this file is where we add our models all right so whatever basically whatever like tables you're going to have you're going to put here so we're just going to have a post table i'm most likely going to do a video where we add authentication to this then we'll add a users table our users model but for now we're just going to do model post and we want to set a few fields here so let's do id we're going to set that to a string so that's the type and then we can do at id which i believe makes this the like the primary key and we can also set a default so we're going to say default and pass in here uuid parentheses that's going to create an id automatically for us in the format of a uuid and then let's do title so title will be string let's just yeah so title string we don't need a default value and then body will be a string and then we're also going to do created at so created at is going to be date date time and for created at i'm going to want the the current date date and time for the default so let's say at default and then we can pass in here now with parentheses and then finally i want an updated at and that's also going to be date time and we can use this at updated at and what that'll do is it'll it'll add whatever the the date and time is when we update and that um you know a post in the database so we'll go ahead and save that and then we want to push that onto our database so down here in the console let's clear this up and i believe it's npx prisma db push okay so now it says sqli database dev db created all right and if we look in our prisma folder now we have this dev.db and i have an sqlite extension so i forget how to use it though oh yeah i have it right here so if you have it installed just search for sqlite in your extensions install it and you can search for it here and then just open database dev.db and it should show up i thought it showed up like yeah down here my my microphone's in my way so right here dev db and if we look we now have a post table with uh you know with those those uh those values not values those fields all right so now i want to create a database seeder so that we can get some some posts in there so to do that we're going to create a file in in the whoops let's close these up we're going to create a file in the prisma folder called seed.js and let's see actually the dev.db you should add that to your git ignore so i'm just going to do that real quick so let's say prisma so we'll do slash prisma slash dev dot db just add that so it doesn't get added to your repo all right and then in the seed file here we're going to bring in since this is run on the server and i'm not using typescript we're going to use the common js syntax so let's say prisma client and that's going to be from at prismaclient so we want to bring that in let's close that up and then let's say constdb set that to new prismaclient and then we're going to have a simple function called get posts and all this is going to do is return an array of a couple of like four posts let me just grab those real quick because we just want to we want to get these posts in the database so this function is just going to return them and you can either grab these from the repository file or you can just copy just some posts with a title and body and then what we'll do is create an asynchronous function called seed oops and we're going to await promise dot all and in here we're going to run we're going to have get posts and then we want to do a dot map and say for each post we want to put put them in the database so we want to return here let's say db that's our database and then post is our model or our table and then we want to create and we're going to pass in an object and set data to the post so we're just mapping through looping through our posts and you know putting putting each one in the database and then we just want to run that seed function here all right so now we can actually run this if we come down here we can say node slash seed and that should have ran the file and now if we look at actually we don't even need that sqlite thing because prisma has a tool i think we can do npx prisma studio and on localhost 555 you'll see here we have under all models we have posts and there we go so we have our four posts in there yeah so prisma is really cool i i plan on doing a video just all on prisma but let's go ahead and stop that whoops did our server stop i think it did okay just make sure this is running all right now that seed we can also add a prisma script in our package.json so in here we can go above the scripts and do prisma and we'll do right here we'll say seed and then we want to run node prisma slash seed and just make sure we put a comma here all right so we're almost ready to use our database there's one more file that we need to create so that's going to go in actually we're going to create inside of our app folder a folder called utils utile i don't know what's wrong with my typing today so in utils we're going to create a file called db.server and we're actually going to use typescript for this so we're going to do a dot ts extension and adding this this dot server we don't need this but what this does is it enforces remix to run this server side okay so that's why we did the dot server and then here since we use typescript we can still use the import syntax and let's say prismaclient i'm going to bring that in then we're going to um declare we're actually going to declare a global scope so this is typescript so we're going to declare our global scope and then actually i think we need to this is from the documentation i believe we have to set that and then set it to a type of prismaclient and then in the global scope we do var and then double underscore db which the type we're going to set to prisma client or undefined and then we want to check to see our environment and and the reason we're creating this file is because in development we don't want to restart the server with every change but we also don't want to create a new connection with every change so this is going to stop it from doing that so we're going to check the process dot env dot node env we'll say if that is equal to production then we're simply going to say db set that to a new prisma client and then db dot and then we can do money sign connect so that will connect else so if we're in development then we're going to say if not and then the global so that global namespace dot double underscore db so we'll say if not then we want to then connect with that so global dot double underscore db set that to new prismaclient and then global dot double underscore db and we want to then dot money sign connect and then right under that if statement we're just going to set db to that global dot double underscore db okay and then we just want to export that db object so now this db this will we can bring this file in to work into any route where we want to use the database and we can then use that db variable to create or read or whatever it is we want to do so the first thing let's go to our posts index so all that database stuff should be all set i know that was kind of kind of weird um but let's go into routes and then let's go into posts and then index.js where we just have our dummy data and then this is where um you know we're going to want to get the post from the database so let's import db and that's going to be from um we actually will use the tilde so from the app folder and then utils and then db dot server we just save that make sure we get no weird errors all right so we're able to bring that in now instead of just defining the post like we did here actually we're just going to replace this array so we'll get rid of that and instead we're going to await because this is asynchronous so we need to set this function this loader to async and then we're going to await db.post.find many okay because we want to find many we don't have to put anything in here but i just want to show you we can add some options for instance we can say take take 20 so it'll just basically fetch 20 posts we can select specific fields if we want oops so let's say id true title true and let's say created at true we don't need the body because remember this is just for this page for the list we're not going to show the body here so we can do that and then we can also order we can say order by and we'll order by created at and we'll order it descending okay so now we're setting we're getting it from the database putting it in in this data.posts and then we're still getting it down here so if i save this there we go now we're actually pulling the data from the database now i do want to just add the the date underneath as well so let's go down here and where we have the the title we'll go right underneath that and let's open up an expression here and we'll say new date just to format this and we'll pass in post dot created at and then we'll add on to this dot 2 locale 2 locale string so if i save that now we can see the dates all right cool now let's work on creating a new post so we're actually done with this we can close that up let's go into the new jsx and right now we're just submitting we're able to you know get the data but we're not doing anything with it so let's bring in our db file so we want to import that from utils slash db server and then let's um i never uncommented that so right here we want to add it to the database and i'm not this we're not doing like a ton of error checking and stuff like that i might add that later on but this is getting kind of long so i just want to get our crud functionality or at least our crd functionality we probably won't do the updating in this video but let's say const post and we'll set this to a weight db dot post dot create and then i'm going to create just like we did in the seed we're just going to set data and we're going to set that to fields okay title and body the created that and all that that'll get set on its own and then when we redirect instead of redirecting to posts let's redirect to post slash and we'll actually use a template string here so that we can go to post slash and then post dot id so let's go to new post okay we'll add post and there we go it brings us to the post page which all we all we're doing there is just showing the the id so we'll we'll get to that what we're going to want to do is fetch that i fetch the single post but now at least we can see it here we have can go to each one so now let's take care of the single page so we'll close that up we'll go to our money sign post id because that's what's what we're seeing here and let's go ahead and bring in from remix we're going to want to use a loader so let's say use loader data um and we don't even need to use params because the loader we can get the params from the loader so we don't need this just get rid of this for now and then let's export function called loader so we want that to be an async function all right and then all we want to get from here we're going to destructure this property and get the params for this object and then let's say const post we'll set that to a weight and then we need our db file so let's be sure to bring that in so that's going to be from utils slash db server and then let's await db.post dot and we're going to use find unique so find unique and we're going to pass in here an object and say where and we'll say where the id let's say where the id is equal to params dot and then post id okay so whatever the url is and then here we'll say if i guess we could have done this in the other one too we'll say if not post then we'll throw a new error say post not found and then otherwise we'll set kant's data and we'll set that to we'll have post in there so we can get that and we'll return data so then down here we can use that hook we'll say const data actually we'll destructure that we'll get the post from use loader data and then this h1 i should be able to output the post dot title and there we go so i'm just gonna add the page header here and then we'll move this h1 into here and then let's just do a back button or back link so we'll do link bring it in from remix to let's we'll say two slash posts and we'll give it a class name of btn and btn reverse and say back okay and then for the body we'll go underneath the page header let's say page dash content and this is where we want to put the body so we'll just do post dot body all right cool now let's do the delete so i want to have a delete button so on this this post id page what we're going to do is add under the page content we'll do page dash footer now this is a little weird we could add a delete event but we can also just submit a form and just add a hidden field letting remix know that it's a delete request because i mean normally you can only do a post or get with a form so let's go ahead and add a form and we're going to specify here that we want the method to be um to be a post request because it's it's going to actually get submitted as a post request but then we just add in the hell's that we just add an input here and it's going to be the type of hidden and then the name we want to set that to underscore method and then the value we're going to set to delete so that's going to let the server know that we want to make this a delete request and then we just want to have a button i'm going to give it a class of btn and btn-delete and we'll say delete let's go ahead and save that so now we have a delete button here and then the way that we handle this is with an action so let's go up here we'll go under the loader and let's say export const action uh we're gonna set this to a sync okay and then we're gonna do const form await request dot form data just like we did in the in the new form now to check the method what we can do is say if form dot get and then we can check underscore method so a form dot get underscore method is equal to delete then we want to delete the the post so let's do const actually we can just copy this right here so we'll go ahead and just copy that and put that right in here in the conditional and then underneath that we'll say a weight db dot post dot delete and this just takes in an object with a where clause so we'll say where and then we'll say where id is equal to the params dot post id now params we need to bring in up here in the action just like we did with the loader so just pass that in params actually we need requests too so let's say request and params because we use requests right here which i misspelled all right so we're deleting where the post id and then after that we'll go ahead and just uh redirect so we'll return redirect which is brought in from remix that i bring it in yeah so return redirect and we'll go to slash pose all right so let's come over here let's hit delete and now the test post is gone awesome go back there we go we get that post there delete and now it's gone all right so i mean this we went over a lot here and you i hope that you can see the the value in this framework rather than having a completely separate back end you know express server or whatever and then having a single page application you have one framework where you can manage everything and i think it's i think it's really useful i do and i think it's the future of react this and next js i think server side rendering is definitely the future it's in and it's funny i've seen a lot of videos and articles that have really said that we're kind of going back to the old days where you know we used php and we submitted the server we submitted forms to the actual server and um you know everything was rendered on the server so i like it i like the direction we're headed but that's it guys hopefully you enjoyed this i will try to get the the the next video up soon where we add you uh user authentication to this so i'll try to get to that soon and that's it thanks for watching
Info
Channel: Traversy Media
Views: 10,584
Rating: undefined out of 5
Keywords:
Id: d_BhzHVV4aQ
Channel Id: undefined
Length: 64min 49sec (3889 seconds)
Published: Thu Dec 16 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.