The Lunch Week Details Component

The Lunch Week Details Component

This lesson preview is part of the Fullstack Svelte course and can be unlocked immediately with a \newline Pro subscription or a single-time purchase. Already have access to this course? Log in here.

This video is available to students only
Unlock This Course

Get unlimited access to Fullstack Svelte, plus 70+ \newline books, guides and courses with the \newline Pro subscription.

Thumbnail for the \newline course Fullstack Svelte
  • [00:00 - 00:06] Thank you for joining us again. We're back to continue working on the front end.

    [00:07 - 00:19] And in this lesson, we're going to work on a lunch week details component. And this component will allow the admin users to view and edit the daily lunch details for a given week.

    [00:20 - 00:27] So we already have a placeholder component called lunch menu admin details. And that's what we're going to work in now.

    [00:28 - 00:34] And here's what the final product after this lesson is going to look like. So we're going to have a save button.

    [00:35 - 00:44] We'll have a publish unpublished button. And then we'll have five text areas for each day in the given week.

    [00:45 - 00:59] So to get that going, we can start with a loading flag and using the on mount life cycle function to fetch down the data for the given week. And we're going to use the lunch week ID specified in the route.

    [01:00 - 01:10] And we'll set that to a state variable called the lunch week when we fetch the data back. So let's copy this part into our script.

    [01:11 - 01:22] And we'll get going. So this is going to be the lunch menu admin details component.

    [01:23 - 01:28] So let's paste that in there. So we're adding just to kind of go walk through it a little bit.

    [01:29 - 01:41] We're adding the on mount function. That's the spelt life cycle function that triggers when a component is loaded to the page, where you're going to use Axios for our network calls.

    [01:42 - 01:59] We're using the icon component and then the refresh icon, which is kind of like a spinner icon. And then when we call export let current route, that allows us to access the name parameters from our route.

    [02:00 - 02:10] And that'll give us to this lunch week ID, which is what's coming from our routes JS right here. So it's this lunch week ID that we declared right here.

    [02:11 - 02:26] And so that allows us to read it out and then use that to go fetch the data for that particular ID from the back end. And then we'll store the result from the back end into a lunch week state variable.

    [02:27 - 02:42] And then we'll have a loading state variable as well. So we could go ahead and test this, even though nothing's going to happen on the UI, we can watch the network tab and make sure that it's working.

    [02:43 - 02:56] And another reason we want to read the state variable from the URL is that it allows us to have book markable URL. So I could just directly go to this URL and say ID number five.

    [02:57 - 03:00] And if it exists, it will bring it back. We probably deleted that one.

    [03:01 - 03:03] So let's try a different one. Yeah.

    [03:04 - 03:11] So here's 11. And so you can see on the network tab over here that we got the data back for that.

    [03:12 - 03:18] So it's working our on mounted hook is triggering and fetching that data from the back end. Okay.

    [03:19 - 03:38] So next, we can add the refresh icon logic to the markup using an if block. And then what we're also going to do here is stringify the lunch week state variable.

    [03:39 - 03:45] And this is just temporary while we're building this. And it kind of helps us watch the state while we're testing.

    [03:46 - 04:06] So let's paste this in just the if else portion with the icon spinner and then the stringified object. Now go right here below nav and before the closing div.

    [04:07 - 04:12] That you refresh it. You can see it real quick.

    [04:13 - 04:22] You can see the spinner. And then here's our stringified object coming back from the server.

    [04:23 - 04:33] Okay. So currently our get lunch week in point is only returning the main lunch week object.

    [04:34 - 04:53] But this page that we're working on needs to interact with both the lunch week parent record and the child lunch day list for that parent record. So we're going to update the back end endpoint to nest the lunch day list in the response payload.

    [04:54 - 05:18] So to accomplish that, we're going to use this helper function get lunch day list and we'll pass in the lunch week ID and then this will run a select statement from the lunch day table where the lunch week ID equals the lunch week ID that we pass in. So over in the back end code on the lunch week dot JS file.

    [05:19 - 05:30] Let's add this helper function here. And then we'll find our get lunch week by ID end point.

    [05:31 - 05:35] So that's this one. And so right here we're just returning the lunch week only.

    [05:36 - 05:50] And so here is where we want to do that nesting. So we're going to need these two lines of code.

    [05:51 - 06:00] So we're going to get the lunch days by awaiting the new helper function that we just added. We'll send in the ID that we got passed in from this endpoint.

    [06:01 - 06:09] And then we'll add the property to this lunch week object. So we'll say lunch week dot lunch days equals the lunch days that we get that.

    [06:10 - 06:22] And that'll add the property into the object and nest it for the response. So let's save that and give it a try.

    [06:23 - 06:30] Okay so this one doesn't have any lunch days. So we get an empty array but we still have that property there.

    [06:31 - 06:41] So it gives us something to work with in it. Let's us know that the back end doesn't have any lunch day child rose for this parent.

    [06:42 - 07:07] Okay so what we're going to do next is we're going to seed the lunch days list. And so where we have the empty array right now we're going to build placeholder objects for each lunch day and we'll write a seeding function to do that.

    [07:08 - 07:14] But we're going to need to do some date manipulation. And so we're going to use a nice library called date FNS.

    [07:15 - 07:36] Date FNS is a modern JavaScript date parsing library and it works well with sp elt and other modern frameworks because you can import just what you need. Whereas you may have worked with Moment JS in the past and that was a much more heavyweight project and dependency.

    [07:37 - 08:01] And so date FNS is getting pretty popular now because it's very lightweight. So go to the command line on the front end project and run npm install date FNS .

    [08:02 - 08:19] And then start the front end backup npm run dev. Okay so we have five text areas, one for each school day of the given week.

    [08:20 - 08:31] And so we're going to build out and seed our lunch days list. But we need to handle some different scenarios as we're looping through to create this list.

    [08:32 - 08:42] We can have a scenario where a lunch day entity does not exist for the given day. Or we can have one where a lunch day entity already exists for the day.

    [08:43 - 08:53] So in the case of our data right now, none of them exist. So we've got an empty array but we might have all five might already exist or maybe even just one or two could exist.

    [08:54 - 09:08] And so we're going to write some code to handle those scenarios. And we'll start by importing some functions from date FNS.

    [09:09 - 09:29] So this is our lunch menu admin details component. And let's copy this in.

    [09:30 - 09:44] And then here's our seating function. So let's copy this in and then we'll break it down some.

    [09:45 - 10:01] So actually this part right here. Earlier we declared the lunch week state variable as just an empty object.

    [10:02 - 10:22] But we're going to have some things that bind to lunch week dot lunch days. And so I'm going to go ahead and change that so that when we initialize our lunch week object, it will have lunch days nested as an array inside it.

    [10:23 - 10:31] So let's get rid of the original one. Change this to let.

    [10:32 - 10:41] So let lunch week and then we'll just declare it with that lunch days array inside it. Okay, so the seed lunch days function.

    [10:42 - 10:56] So what we're going to do is first of all figure out the week of date. So back here, that's going to be this date right here.

    [10:57 - 11:06] But when we get it back from the server, it's just a string. So the first thing is we're going to do is parse it into an ISO date.

    [11:07 - 11:18] And that'll allow us to use other functions to other date functions to work with it. So we're then we're going to loop five times one for each day.

    [11:19 - 11:26] So it's just a simple for loop. Let I equals zero, I less than five.

    [11:27 - 11:37] And then so for each iteration, we'll add one to this date. And we'll get a formatted day.

    [11:38 - 11:55] And that's just going to get us a nicely formatted version of that. And then we're going to check to see if this formatted day, which is your year, month, month day day, that's the same format as this.

    [11:56 - 12:04] We're going to check to see if this already exists in the array. And so that's what this sum function does.

    [12:05 - 12:18] So as we're iterating through, we want to make sure that the one we're about to create doesn't already exist. If it does exist, then we'll just continue and exit out of the loop and go to the next iteration.

    [12:19 - 12:30] So if it doesn't exist, then we'll create a new lunch day object. And it will have the day will be equal to the formatted day.

    [12:31 - 12:41] So we'll match this JSON format. The lunch week ID will be the lunch week ID of the parent, and then we'll initialize the menu details property to null.

    [12:42 - 12:55] And then we'll splice that in to the lunch day's array. The reason we're using splice here is that it lets us put it at a specific index, whereas push would just add it to the end.

    [12:56 - 13:11] And so like we said, we could have a weird scenario where maybe Tuesday already existed for some reason. And so then we'd put Monday in and we'd splice it in before Tuesday, then we would skip Tuesday, then we would splice in Wednesday after Tuesday.

    [13:12 - 13:25] So this just handles operating on the array at an exact index when we want to. Okay so that's our seed function.

    [13:26 - 13:44] And then what we're going to do is call the seed function in the on mount function. So right here we'll call seed lunch days.

    [13:45 - 14:05] And so once we get the response back from the server, we're going to manipulate it a little bit on the front end to set up what we need to on the front end. So now if we give this a try, now we can see our array is populated on the front end at this point.

    [14:06 - 14:20] Okay so the JSON, our underlying state is in good shape. And we can add buttons and text areas to the markup.

    [14:21 - 14:42] So we're going to add a couple of buttons that let the user save or publish slash unpublished. Okay so right below our stringified object there, we're going to add this section.

    [14:43 - 14:56] Down here in the markup before the if block ends. So we're going to have a button group that'll have a wrapper div and then we'll have a save button.

    [14:57 - 15:12] That save button is going to call a save function that we haven't created yet but we will. And then we'll have a publish slash unpublished function and that's going to call a toggle publish function.

    [15:13 - 15:26] So we're going to use a turnary here for this button label. So if the lunch week is published then the button will be called unpublished because it's going to do the opposite of what the current flag is set up.

    [15:27 - 15:32] Else we'll call it publish. Okay.

    [15:33 - 15:44] Now we're probably getting some build errors here. So it says save is not defined toggle publish is not defined.

    [15:45 - 16:10] So just kind of a reset back to some errors you could get on your console if you haven't defined everything that you're depending on. So we've created a list and of lunch days and we've got five items in that list .

    [16:11 - 16:32] And so we can use that to build our text areas and we're going to use a spelt each block to do that. So below the buttons we just did we're going to add another section here.

    [16:33 - 16:45] And we're going to give this a margin top two just to push it down a little bit visually and then we'll create columns. So we're going to have one column for each day in the list.

    [16:46 - 17:00] And so we're going to let spelt actually build this markup here with an each iteration. So this markup right here will be repeated five times once for each day in the list.

    [17:01 - 17:23] So we'll have five columns then in each column we'll have a div with a class field. That's the form setup using BOMA then it'll have a label and we're going to dynamically build these labels by formatting the ISO string date from the underlying state.

    [17:24 - 17:33] And this is a format that's going to give us a nice day of the week and then date. We'll see it in just a second.

    [17:34 - 17:53] Same will have the actual text area and because we're inside this loop that lets us bind the value from the text area to the correct row inside the array. And so everything will work nicely with our front end text area input and then the underlying state.

    [17:54 - 18:03] Okay. So let's see, yeah, so this is actually working.

    [18:04 - 18:14] And so here's what our front end looks like now. So we've got our nicely formatted date label at the top there and then we've got our text area inputs.

    [18:15 - 18:26] But we're still getting those errors with our missing functions. So let's add the save and publish functions.

    [18:27 - 18:41] So here's the save function. Copy that one in.

    [18:42 - 18:56] And so what this one's going to do is iterate through each lunch day. And if the lunch day has a lunch day ID, then we're going to call a put.

    [18:57 - 19:20] So it's going to update the existing row following our API convention with the lunch day ID and then the lunch day as the body. And if it doesn't have a lunch day ID, so none of the ones that we have right now have lunch day IDs because they don't exist on the back end in the database.

    [19:21 - 19:41] So if it doesn't have a lunch week ID, then we'll do a post and we'll get that response back and set it into the object that we sent in. So it will populate it when it comes back.

    [19:42 - 20:00] So that's the save function. And then let's paste in the toggle publish function as well.

    [20:01 - 20:16] And so this one's just going to set the parent lunch week is publish flag to the opposite of whatever it currently is and then run it put to send it to the back end. Okay, so we should be able to give these a try now.

    [20:17 - 20:27] So let's just say test there. And you can see as we're typing, it's automatically two way bound to the right item in the array.

    [20:28 - 20:39] And then when we hit the save button, this is where our save function kicks in. So we're going to run five post statements.

    [20:40 - 20:44] And so you can see all of those there. And so now this is stored in the back end.

    [20:45 - 20:57] So if we hit refresh now, pulling it down from the server and we can see that our data is persistent. And so now each of these lunch day objects has an ID.

    [20:58 - 21:07] So in this case, we would hit the post option. We hit the save button.

    [21:08 - 21:17] So now we've got, or excuse me, put. So now we've got put calls being made to the back end.

    [21:18 - 21:33] And then our publish function, toggle publish function here, if we click that, let's see, we've got an error there. Okay.

    [21:34 - 21:55] So at this point, when we click the publish unpublish function, we get a 500 error. And so we can see here it says update lunch week, et cetera, et cetera, column lunch days does not exist.

    [21:56 - 22:15] And so the reason we're getting this error is because we're sending in our lunch week object with the lunch days nested on it. And our back end controller with next doesn't know how to translate that into SQL and handle it.

    [22:16 - 22:38] So we can fix this on the front end by making a copy of the lunch week object and removing the lunch days property prior to sending it to the back end. Now if we just deleted the lunch days property, Svelte would react to that and it would cause a bunch of havoc in our front end.

    [22:39 - 22:49] So we need to make a copy first so that we don't have a pointer to Svelte, then we'll send that copy end to the back end. And then that's what the back end will use.

    [22:50 - 23:05] And another benefit is that Svelte won't react and change the publish button until after the network call successfully completes. So here's what we want to do in our toggle publish function.

    [23:06 - 23:31] So first we'll stringify and parse it to make a copy. Then we'll use our copy to toggle that flag.

    [23:32 - 23:54] And then we'll delete the lunch days property from our copy. And then we'll send that payload copy in instead of what we were doing before sending the lunch weekend.

    [23:55 - 24:11] And then upon success, then we'll change the property on the main stateful object. Okay, so let's give that a try.

    [24:12 - 24:34] And now if we hit publish and we look at the body here, we're only sending the parent object in and we don't get the error so we get that saved. And likewise, when we toggle it back to unpunished state, we'll get that.

    [24:35 - 24:44] Okay. So another little thing we can do with Bulma is use the is loading class to the buttons.

    [24:45 - 24:58] And this is a nice way to let users know that something is happening when they use the save or publish buttons. So we're going to create a little bit of state called saving and publishing.

    [24:59 - 25:17] And then we're going to use ternary expressions to apply additional classes to those buttons while that condition is true. So we'll start with the state here.

    [25:18 - 25:23] Paste that in. So saving and publishing.

    [25:24 - 25:42] So on the save function, we'll set saving to true at the top of the loop. And then at the end, we'll set it to false.

    [25:43 - 25:58] Likewise with publishing. So that'll toggle that state there.

    [25:59 - 26:12] And then we need our ternary expressions here in our markup. So I'm going to copy this markup here.

    [26:13 - 26:32] So basically where we have static classes right now, we're going to use a tern ary expression in JavaScript to dynamically add in the is loading class. So it would look something like that.

    [26:33 - 26:49] So with Svelte, we can easily use JavaScript for any HTML property just by using curly braces. And so what we're saying now is class, if saving, then we'll add the is loading part.

    [26:50 - 26:57] Otherwise we won't have the is loading part. Now these are going to be very fast, so it's going to be a little hard to see.

    [26:58 - 27:06] But you might be able to see it a little bit on that save button. So you get a nice little spinner icon.

    [27:07 - 27:26] OK, so here's the full Svelte file for everything from this lesson. I know it was a little bit much, but you can look here and kind of copy what you need to if you missed anything.

    [27:27 - 27:30] And that's it for this module. Awesome work.

    [27:31 - 27:38] So we did a ton in the front end. We deleted data with an X button and our delete endpoints.

    [27:39 - 28:00] We created data with an add button and our post endpoint. And then we did something even more complicated here where we seeded our lunch day objects and then have some functions to either post or put those and then toggle our published flag on the parent record.

    [28:01 - 28:09] And that's just awesome work. If you've made it this far, then you're well on your way to understanding Svel te and building a full stack web app.

    [28:10 - 28:22] And in the next module, we're going to switch gears and work on security. So as we touched on before, our app doesn't have any security right now and our API is completely public.

    [28:23 - 28:39] So we're going to address that next and we'll work with JSON web tokens and make sure that only authorized/authenticated users can view and update the data that they are allowed to work with. That's it.

    [28:40 - 28:45] We'll look forward to seeing you next time. .