??? Visit Chris @ Coding in Public for more of his tutorials:
https://www.youtube.com/c/codinginpublic
???Get early access to his entire course now on Net Ninja Pro:
https://netninja.dev/p/budgeting-app-with-react-router
??? Access the course files on GitHub:
https://github.com/coding-in-public/react-router-budget-app
??? Live demo of the finished app:
https://codinginpublic.dev/projects/react-router-budget-app/
??? React Router in Depth Tutorial:
On Net Ninja Pro –
On YouTube –
??? React Router docs –
??? VS Code –
All right so we've got a lot of things Functioning in our app properly I can Create a budget category and then I can Add an amount and if I hit enter or Click create budget you see it submits It there we get this nice pending state It refocuses this clears out the form And gives us a notification now you Might remember that in the dashboard Itself what we've got is this showing if We do have a user and this intro is Showing if we don't so just to show you What that looks like I can come over Here and click delete user this is the Intro that's showing right here as soon As I add in my name like this it should Now create an account and welcome me Okay so now we've got this set up and Ready what I want to do next is add a Form here where we can submit expenses So if I jump over to the finished app This is not something I've been showing You a whole lot but if I come over here To groceries and whatever I add 1200 now You'll see that now I get this option to Add different elements now there's a Couple things we want to pay attention To eventually we're going to get down to All this but you can see here I can add An expense but it's scoped to the Groceries because that's the only budget I currently have and I'll add this as Like 120 or something if I were to Create another budget though so like
Budget 2 or whatever for 1200 now you Can see I get this drop down where I get To choose between groceries or budget Two so we want to set it up like that to Where this is optional and it will show Basically if we have more than one Budget otherwise it will just scope it To the budget that currently exists all Right so that's what we're going to work On next is this form but to do that we Need to kind of restructure how some of This works and a lot of that's going to Be using this now rather than trying to Put all of this inside of here I think The easier thing to do would just be Delete this and then recount of set it Up like this so let me go ahead and Surround this with these curly brackets And we can have an optional Little Section depending on what we decide here So right here I want to check on a Couple things first of all that budgets Exists and that I have budgets.length And that that would be greater than zero So in other words it can't be an empty Array so if both of those things are True then I want to add all of this Stuff right here Otherwise down below we're going to do Something very similar to what we've got Up this way so let me actually go ahead And give this a little bit more space Just so it's a little bit easier to read Then down here what I want to do is I'm
Going to add almost what we currently Have but I'm going to change it just Slightly by putting everything inside of A grid a small container then I'm going To add two paragraphs of text the first One saying personal budgeting is the Secret to Financial Freedom and then Right below it here we'll have it create A budget to get started And then lastly I just want to go ahead And copy this down and we're going to Add it down this way so if I don't have Anything let me move back to our current Code and I've deleted all of the Application data over here so right here I've deleted all those budgets so this Should be showing right here and you can See that personal budgeting is the Secret to Financial Freedom create a Budget to get started perfect so once I Create a budget it should remove that Text so groceries and I don't know Something and you can see now hopefully There we go it disappears okay so now We're in this section I do actually want To change this up a little bit as well So we are going to have stuff in a grid Large container here but what I want to Add down here is another form so Assuming that I have a budget then I can Go ahead and show the expense form so Add expense form is what I want and I Actually want to pass down my budgets to It that way I can decide in that
Component how many budgets to show based On how many budgets I've saved so that's Where we'd get that little drop down so I'm going to just pass it down as a prop Of budgets just like this now we haven't Created this yet and and we could pretty Much copy most of the stuff from ad Budget form but I think it actually Might help just both with practice and Hopefully with Clarity to go ahead and Build it once again from scratch so if I Say this we're going to have a problem Because this is not defined you can see Our custom error message is showing There as well which is kind of cool but Let me come over here open up the Sidebar we'll come right inside here and Add another component this is going to Be called add expense form So I'll template this out and then we've Got that there let me now come over here And just make sure I pull this in up top So we'll copy this down grab both these And say add expense form all right so There it is at expense form showing up For us now let's actually style that so Let's open this back up and once again We want to do several things that we've Done before in the past with this just Like we did with our ad budget form to Start with I want to add a class here It's the same class we used on the other One and that is classiform wrapper and Our CSS should style that now with that
Nice dotted line then I have an H2 here With a class of H3 like we did before This will say add new and then here's Where we're going to have a difference Depending on whether or not we have one Budget or multiple budgets so here we'll Have a span with a class of accent We're going to ask this question does Budgets.length Equal one and only in that case then I Want to render out Budgets.map we'll call this budge and We'll just render out the budge dot name If I were to save this it's going to Give us problems because we have not yet Accepted the prop in here so we need to Accept budgets And you might remember that we passed That in let's see down this way so right Here this is what we're accepting now Right here and then we're running this Little ternary off of this well having This logical and that basically will Show this text if we have a budget's Length of one so here you see add new Groceries and then at the end of this Let's see inside the H2 but outside the Span I want this to say expense And then just to make sure these spaces Work properly let's add them like this And I'll do the same thing right here All right perfect hopefully that's clear As mud all right now below the H2 is Where we're going to add our form now
You might remember we're actually going To use the same kind of fetcher function We did before so I'm going to go ahead And pull in up here const fetcher equals Use fetcher all right again that should Import up top here with react router Dom And now I can grab this right here and Say fetcher.form And fetcher.form okay perfect now just Like a normal form we're going to add a Method on here and we'll go a little bit Faster since we've done this before but I'll add a method of post and then I Want to add some classes as well and These should look familiar so we'll add A class name here of grid small And then I do want to add a ref to this As well and this will be our form ref Now we need to actually declare these up Here so let's go ahead and say const Form ref equals use ref and this should Come from react and let me just go ahead And grab this up here we'll call this React router Dom Imports and this will Be react Imports All right so now we've connected this Ref right here to this use ref hook Inside here I'm going to actually add Everything inside of a div with a class Of expense inputs and this is again just For styling purposes this will set the Names side by side this will set the Name and the amount of the expense side By side when it's appropriate on the
Screen now just like before each of These are going to be inside of a grid Extra small just to keep the labels and The inputs next to each other this one Will be called new expense and we'll Just simply say expense name And then we need to go ahead and add an Input here this will be a type of text But let me go ahead and move this down This way like that And then we'll give this our name of new Expense And we'll also set that as the ID as Well now for the placeholder we're going To set this as EG coffee just to give an Example and then for the ref we want to Point this to what we'll call this Focus Ref like we did before So let's come back up top here and let's Go ahead and declare that so I'll call This Focus Ref And then come back down here all right After the focus ref we want to make sure That this is required and then we're Going to do it again so let's come down Here and we'll add another grid extra Small and this will have a label as well This label will be new expense amount And we'll simply call this amount for The actual visible label Then below here we'll have an input this Will be a type of number and just like Before we want to go ahead and set a
Step so that the step increment will be By 0.01 and then input mode will be also Set to decimal like before again this Makes it to where on mobile devices you Actually get a decimal or like the Number pad with a period or decimal I'm Not sure where that's doing up there so Let's get rid of that and come down Below here we'll set the name here to The same thing so new expense amount Copy that down and then the ID so that The label and the input are pointing to Each other The placeholder here will simply set as Like 3.50 to give an example and then We'll set required so they do have to Provide an actual amount now we want to Come down here and inside the form but Below these divs here we want to go Ahead and add that optional section that May or may not display if we only have One budget it should not display if we Have more than one budget it should Display for now let's just set this to Grid of extra small just like before This will have a label we'll call this New expense budget And we'll name this budget category Below here we're going to use the select Option and set this name to the same Thing so new expense budget and the same Thing for the ID new expense and budget Now once again this needs to be required So they have to choose one of these
Categories and it should Auto Select the Very first one so inside here assuming That we've got budgets which again it Should never be visible because the way We set up our dashboard unless we've got Budget so we don't need to actually do a Check here we can just say Budgets.sort because I actually do want To sort these and I want to sort them by When they were created now you might Remember that each of these budgets is Going to have a created at property on Them so we'll say a.created at Minus B dot created at So they should now be properly sorted Let me actually move these down here and We haven't yet outputted these so it's Yelling at us but that's okay we're Going to say now we want to map over These we will call them budgets because That's what they are and we simply want To return some jsx so this will be an Option element here and the value is Going to be the budget's ID so budget Dot ID And because we are creating a map here We also need to have a key for react and We'll do the same thing so we'll say Budget.id now the actual display value Will be the budget name so budget Dot name So I'll walk you through that again in a Second but just note that what we've Done is take our budgets that we passed
In up top let's see right here and We're Looping over each of those and sorting Them by when they were created so the The last one created should be first Etc all the way down the list then You'll notice here that we're mapping Through the budgets and for each budget We're returning this bit of jsx we're Going to give it a value right here so That when we select this and submit our Form this is the budget ID it's Connected to and then the budget name Will be what's displaying right here if I drop this down you should see there's Only one and you might remember that we Don't want to show this if there's only One so how do we do that well I'm going To come up top here to this whole div Right here and we're going to say that It needs to be hidden if the budgets dot Length is equal to one so now that we Know it's working I'll click save and it Should hide itself and that's what it Does so if I were to add another budget For instance I came in here and added Whatever that is and hit create now it Should show and that's what it does and That little Spain we had disappears all Right now this is all fine and well but We don't yet have a button to click so Let's come down below here right inside This fetcher form close and we want to Do two things first of all we need to Add another hidden input so hidden you
Might remember that we are using these That have a name of underscore action And that will tell us what we should do With the form when it's submitted here We want the value to be create expense And then below here we're going to have A button and this one will be so similar Again to that add budget formula let's Just go ahead and copy that so we don't Have to redo all this because I think at This point we're pretty clear with where We're at on the form I'm going to copy This out come over here and we'll paste This in right here now we've got a Couple things we've got to change Because if I were to save this we'd get An error because we have yet to actually Determine what is submitting and what's Not submitting from the fetcher so That's one thing we need to change I Also want to change what this says so This needs to say add expense and then I Also want to change the this currency Dollar icon so I want this instead to be Plus Circle icon and you can see it's Actually pulling in there so I'll go Ahead and do that come up top here and Let's go ahead and move this up I'll Move this down we'll call this Library Imports And while we're up here let's go ahead And set my const is submitting to Fetcher dot state if that equals
Submitting so now if I save it Everything should work and it does Okay Cool so I've got this right here we have Yet to handle that form but there's one More thing we need to do because this is Submitting we want to actually set some Stuff based on that and you might Remember that right here that's one of Those things we want to set this to say Submitting all right so let me come back Up top here and let's go ahead and use Our use effect hook so use effect and Our dependency array here we'll simply Take in is submitting And just like with our ad budget form We're going to check if it's done Submitting so if it's not submitting Then I want to do two things number one I want to clear the form and number two I want to refocus this selection on the Name of the expense so clear form And then reset Focus so we'll go former F dot current dot reset and then next I Want to focus on the focus ref so Current dot Focus All right uh submitting is not defined You're right this should be is Submitting Okay so there we go so I should be able To come in here add something add an Amount and then select a budget category My first one I created should be first All the rest should be below and then it Should submit now it's obviously got a
Problem right now because we didn't do Anything but we can go back and return To this page so let's actually handle This now over in the dashboard so we've Submitted this form and you might Remember once again that we've added a Hidden type right here with the action Of create expense so we can handle that Over here in our action so I'll come up Top here and create another option in Addition to this one if action this time Equals create expense then instead of Creating a budget I want to create an Expense And then add some kind of toast message To say congratulations otherwise we'll Say there was a problem creating your Expense All right so first of all just to make Sure this is working properly let's Change this around we'll say expense and Then in this case we actually want this To be inside template strings and this Will be values dot new expense which is The name of the expense we'll say that's Been created so even though it's not Going to actually create it right now We're going to get a success message Because the way we set this up I don't Have anything I'm getting back from Local storage here so I'm just going to Assume that everything is working Properly again obviously you'd probably Be submitting this to a database but you
Can see there is expense coffee created Okay so we're set to go there now we Just have to create a little helper Function to actually create an expense So let's get rid of this and we'll Eventually pull it in but for right now I want to open up my helpers.js and Let's see we've created a budget we're Going to do a lot of similar stuff so Let's just copy this down and then we'll Create an expense so right here create Expense and expense that should work Now the first thing I want to do is we Do have this ID that's right we do have This name also correct created amount That's fine amount we don't need a color But I do need something else so I need The budget ID We're going to get that from budget ID That we pass in again I don't have to Pass those both in but just to show you That this is work what we're going to be Getting in up here we're going to pull In a budget Oops budget ID All right just like that now we do want To look at existing uh expenses not Budget so let me grab this and I'll hit Command D on all those and change this To expenses and so we should fetch the Data for expenses if they don't exist if This is null or undefined I will get Back an empty array and then what I'll Do is I'll set the item expenses to
Whatever my existing ones are so this Should be expenses here as well and then We'll also pass in this new item so now All I have to do is actually use this so Let's come over to the dashboard once Again and right here where we're trying Something let's go ahead and try to Create this expense you'll see I'm Getting an import statement there just To make sure it came in properly let's Go check on that there it is create Expense okay perfect Now you'll see here I've Got a Name an Amount a budget ID so this is all going To be inside of an object so I don't Have to remember what order to pass them In I just have to name them so the name Here will be the name of our field for New expense so values.new expense is What we call that and then next we've Got an amount so this will be a mount This will be values.new expense amount Even though we're passing it in as a String you might remember that we're Actually converting it here to a number With this little plus sign all right Finally then we actually need to pass in The budget ID now where would we get That from you might remember that each Of those select options had an actual Option that had a value which was the ID Of the budget that's where we're getting This from so values dot new expense Budget
All right so let me walk you through This one more time assuming that it Works so should we test it out first Probably so let's come over here and I'll add a coffee like this 1.2 whatever Groceries that works before I hit submit Let me open this up and let's look at The application right here so we don't Have any expenses yet now if I click This it should add them there we go all Right cool we had a little delay there Because of our fake uh data loading kind Of function so there's our amount There's our budget ID that it's Connected to when it was created the ID And then the name all right cool so it's Actually working let's now talk through It once again so when this is displaying If I come over this way we've got Several fields that people can fill in They've got to fill them in in fact the First is the name so they've got to give It a name they've also got to give it an Amount so that's these two right here Then we've got a budget category down Below so this budget category is going To give us a select with multiple Options for each option it's going to Have the value set to what whatever the Budget's idea is so we can capture that When we create the new expense now Because I've come down here and I've Added this type of hidden with a name of Underscore action and I've set it to
Create expense when I submit it to its Current form because you remember our Form up here our fetcher.form I suppose It doesn't actually have an action so it Should just submit to the page it's on In this case that would be the dashboard So the dashboard is going to handle that And if I come over here we've checked on What the action is if it's create Expense then we've tried to create an Expense we've passed in the name the Amount and the budget ID then we've Returned a toast message we've caught Any errors that happen to happen all This is happening inside of our action Then it's actually using our little Helper function to save this to our Local storage and then giving us a Little toast message to say that it has Been successful now in the next video we Actually need to display these budgets Down below here we'll eventually display The expenses as well but I want to Actually see what budgets I have Available and little carts and in fact If I come over here to the finished uh The finished code you can see here here This is what I want it to look like so We're going to create these things next That will show how much we've created And it will actually look and see how Many expenses are connected to that Budget based on all the data we just Gathered all right well I hope you're
Ready I will see you there