Svelte Tutorial - Is it better than React?

freeCodeCamp.org · Beginner ·🌐 Frontend Engineering ·6y ago

Key Takeaways

Builds a Svelte app using routes, forms, and CRUD API

Full Transcript

No, not another JavaScript framework, please. Don't we have enough of those? But, what if I told you that this isn't actually a framework? It's a compiler. Mind blow. All right, hello class, and welcome to this video where we learn about what Svelte is, and then use it to create an app that implements full CRUD functionality by using an API that I created a while ago for a video to which a link is in the description, and the link for that API as well will be in the description. More on that later. So, what is Svelte, and what makes it different to the other ones? So, like Angular, React, and Vue, Svelte is a UI framework for creating component-based single-page applications. The catch is that Svelte takes a different approach in that it doesn't have framework code that's actually bundled with your application. It actually goes over your code in build time, and then compiles all of your code into instructions in written in purely JavaScript, leading to a very lean bundle size because later your bundle wouldn't have any code that's relevant to Svelte itself. It's just your own code that you have. And Svelte as well takes a reactive approach when re-rendering your DOM, and and it doesn't have a virtual DOM. So, it doesn't work by com- rather comparing a virtual DOM to an actual DOM, and then seeing the difference, and then re-rendering the difference. Instead, it watches over a couple of variables that you define, and then whenever any of those change, it actually re-renders the DOM. So, they take great pride in that it takes less code doing the same thing you could do the same thing in React and do it in Svelte, and it will be less code when you write it in Svelte. You can actually go here to learn more and write less code, and you will see a couple of examples they show that, for example, this is with these two fields and calculating the sum between them. This is what it would look like if you would write it in React, uh using hooks. And then this is what it would look like if you write it in Svelte. And uh I've I've played around with Svelte and it's actually pretty cool how how less code you get to write. And even like the template syntax itself is very minimal and it's got some really cool features. Now, this doesn't mean it's going to replace React or anything. Uh React still has a lot of like improvements during the runtime and and some other cool features that are in the bundle itself. Uh so yeah, I guess it's up to your preference. Now, if you are saying now I want to learn more about uh Svelte, you can go to svelte.do- .dev rather and learn more about it. And if you want to like understand like the the idea behind it and the philosophy behind it, I highly recommend this talk by Rich Harris, the guy that made the framework himself. Uh this talk is called Rethinking Reactivity. I'll put a link to this as well in the description. It's a really cool talk that kind of explains why Svelte was made. All right. So, this is the application that we're going to build uh in this video. So, it's got these uh posts. It's pulling them from the API, so it's fetching these posts and showing them here. And we can add some more new posts, so we can click add here using that form. And we'll actually submit it to to a server and fetch the um the response back. And if we reload, it's still there because of the way the API works. We can as well edit these, like just type some other gibberish here and click update and it will be edited. And we can delete these posts. Uh we can limit the number of posts. And we have the snack bar right here and we have like two pages that we can navigate between just to show you like how to do routing in Svelte. So, the idea behind uh this app is that you get to learn some of the core things that you would do in a in most front-end applications like handling forms, uh consuming a full CRUD API, and routing as well. So, let's actually jump into the code. All right. So, on the Svelte main page, let's go down and get this MPX command from here. Let's copy this. And I'll go to my desktop and open up a terminal window and paste this command. And we don't have to name it my Svelte project. You can name it anything. I'll just name it Svelte for now and hit enter. And then now we need to CD into it. Also, I'll say CD Svelte. And here we need to run NPM install because it hasn't installed the dependencies yet. And I'll open it using VS Code and let it install. So, if we look at the package.json, we notice that we have a couple of scripts. We're going to use the dev script to build and run the app on a development server. And if you notice here, there isn't any dependencies. It's just dev dependencies cuz it doesn't need any dependencies in production. It only needs them in build time to compile the app. So, here I think it's done installing. It has. Let's run NPM run dev and see what our application looks like. All right, it started already. So, let's go to port 5000 here. And there we go. We just get a a purple hello world. So, let's look at our app. So, we go to the source folder and we have this main.js that instantiates the new Svelte app and passes some props to the app.Svelte just to show you how props work. They did that. And here we get the prop and here we put the prop inside the markup saying hello name. If you notice we if you change this name to hello YouTube or just YouTube, it will now say hello YouTube. All right. So, let's get rid of these props cuz we're not going to use them. Let's get rid of this export let name and this style as well. And by the way, in Svelte, if you've worked with Vue, you're familiar with this with this kind of syntax. You have a script tag where you put your logic, you have a style tag where you have put your styling, and you have your markup. The only difference here, you don't have a template uh tag. You just put your markup down here. And uh cool thing is if you're um using Prettier, and by the way, uh I recommend you get the Svelte Where is it? Right here, the Svelte VS Code extension to have uh syntax highlighting inside of your app or I mean inside of your dot Svelte files. All right, let me close that. Close this. Now, before we write any markup, I want to grab uh Materialize CSS, which is a cool CSS uh an implementation of Google Material Material Design standards. Uh let's go to get started. And here it tells us to install Materialize CSS at next. So, let's do that. So, here I'll I stop the development server and say npm install materialize -css at next like this. Okay, now we need to link the CSS. Uh we could link it here. We will. But uh by default, the build tool for uh the bundling tool for Svelte is Rollup instead of uh Webpack, and it comes with very minimal uh setup. So, we need to actually install a uh a plugin for this for it to actually recognize CSS files inside of the Svelte files and bundle them into a CSS file in production. So, here I'm going to install a Rollup plugin. So, here I'll say npm install uh Rollup plugin css only. And uh say dash uh capital D for it to be uh a dev dependency. All right. Now, in the uh Rollup config, I'm going to add this import. Let's import that plugin. So, let's say import CSS from uh Rollup uh plugin css only. And then here, underneath this uh Svelte uh call, we're going to say CSS. We call that uh namespace that we imported, that function. And here for the options, we just pass output. And here we will pass a CSS file that would be all the bundle CSS that we pass to the to our app. So here I'll say public {slash} extra.css. So what this plugin now will do, it will find any CSS that we inject into Svelte files and and bundle all of it into this extra.css file and it will be in the public right here. So we need to link it in our index.html. So here let's link it before our actual CSS. So here we'll say link and we say the href will be extra.css. Even though it doesn't exist yet, but it will. Let's change the title here so it says Svelte tutorial. And let's save this. And let's go back to our app.svelte. Now we can actually import CSS into this Svelte file. So here we'll say import. Now that we have Materialize installed, we can say import. We go back one level to node modules. node modules {slash} materialize CSS {slash} dist {slash} CSS {slash} materialize {slash} CSS.min Actually materialize .min.css like this. And we can just copy this to get the the JavaScript and here we'll say {slash} js and here will be .min.js like this. Now let's let's save everything. And let's run our app again. Let's say npm run dev. And now we see that it created this extra CSS and it's got Materialize stuff as you see here and it's actually linked Materialize. And if we would look at our app, where is it? Right here. If we reload, we get that it's the header is now styled with Materialize uh, CSS header one styling. Cool. So, we have Materialize linked. I want to start by, um, putting a navbar at the top of the page to link to different pages. Now, of course, the about page is empty. I'm just using it to show you how to do routing in Svelte. So, we're going to use this, uh, Svelte routing library because, uh, by default, the routing library doesn't come with Svelte. So, this is how to re- use it. We need to run this command right here. So, let's copy that and, uh, let's open up a new window, terminal window, and paste that, uh, command. So, if we look at the, uh, library here, it tells us how to use it. It tells us to import these things from Svelte routing, so we can, um, we can copy this. And let's go to our app, uh, app.svelte. Can close these. We don't need them anymore. So, here we will import these, um, router and link and route from Svelte routing. And now we can set up our router here. So, here we'll say router. And then here we will start to put, uh, our routes. But the way I want to do it, I want to put them in a navbar. I don't want to put them right here. I want to put the navbar in its own component. So, let's go to, actually I closed it. Let's go to Materialize CSS. Go to components, and, uh, right here, navbar. Let's grab this, uh, nav tag. Uh, let's go back, copy that, and let's click, uh, here. Let's create, rather, a new component. And I'm going to put this in a folder called layouts, so I'll say layout/navbar. dot svelte. And here we'll just paste that. Let's change logo to, uh, say Svelte, uh, tutorial. And, uh, let's change these. Let's just have two pages. So, one would be the home page, and one would be the about page, and we need to create these components as well. And, uh, now these shouldn't be, uh, A tags. They need to be links for our Svelte router to work. So, here we will change this uh, anchor tag to link like this. Uh link. Now, of course, we need to import it. So, here we need to put our script tag. And here we will say import link from Svelte dash routing like this. Now, we can use that. So, we can change as well the the brand to link like this. We need to add a two attribute instead of href. And this is the home, so we'll say two slash. And now we have this home link here as well. So, we'll say two slash like this. And we will change this to a link. And this is the about page, so we'll say two uh slash about. And change this here to a link as well. Now, let's go back to our app. Here we need to put our navbar. So, we need to import it. So, let's go here and say import navbar from And on the same level, we go to the layout folder and we get this navbar. And here, of course, we have to add Svelte because um it's not a JavaScript file. We need to explicitly say what the extension is. Now that we have navbar, we can actually use it in our markup. So, let's put it inside the router. So, let's say like this navbar. Oops. Apparently, I didn't copy that, so I can just say navbar like this. And underneath here, I want to put a container to push everything into the middle. This is, by the way, just materialize stuff. And here we need to put our routes. And if we would look at the page for the package, our routes are like this. And by the way, you can ignore this URL thing. This is only if you're using server-side rendering, so don't worry about that. And let's copy one of these routes. Let's copy the second one, actually. And let's go back. Here we need to put routes, so let's put the home route. The path will be just slash and the component will be home. And by the way, you can use the syntax, but you can as well emit these quotation marks. They're not important. So, they're not necessary. So, let's put another one here and say slash about and this will be to the about component. Let's create these two pages. I'll create another folder, call it pages. Uh this is what convention that I like to separate pages from components. This is not a Svelte convention. So, here I'll say home.svelte and I'll create another one as well, call it about.svelte. And in the about, I'm just going to put a header one saying about page just to differentiate between them. And here, for now, let's put home page and we'll come back to it, of course, and populate it more. And here we don't need link, so we can remove it because the links are in the navbar. And we need to import these two components. So, here let's say import home from same level pages/home.svelte. And then we can copy that. Paste it one more time, select home and control D and say about. All right, let's save all files and let's look at our terminal. Everything is running fine. If we look at our app, right, where is it? Right here. If we reload, cool. We get this navbar and it's linking between the pages, but it looks kind of weird. Let's look at our app. I think it's got to do with the the global styles. Yeah, there are some global styles here. I'm just going to delete all of them. And let's look back to our app because we're going to use the materialize styling. All right, let's put a container actually to push these buttons in. And for some reason, this brand isn't uh the font size is tiny on that, so Actually, let me check that. So, inspect. It's actually not applying the class to it, so and let's go back here to the navbar. The brand logo class is not being applied, so what we can do, we can just wrap this Svelte tutorial with a span with this class, so we'll give that class brand logo and then take that, put it inside of here, and then wrap everything here, so let's cut everything inside of this nav wrapper and put a dot container tab and then paste back those links, and let's save. And there we go. Now the the the navbar logo class is applied, so the text is bigger there, and the links are pushed in inside. So, the routing is working now. We can start to work on the content on the home page. Let's start to hit our API and fetch the posts and show them here. So, let's go to our app, let's go to the home.svelte file. And we can close this, close the global.css and app, and everything else. And here I'll put a row, and inside of here we want to show our posts, but of course we need to hit the API first and fetch these posts. So, here I'll open the script tag. Let me close this terminal. Here inside the script tag, what we want to do, we want to fetch these posts when the component loads or mounts. So, we need to import this life cycle method called on mount, so let's say import on mount. This is in the documentation, of course, from Svelte. And here let's let's bring our API base URL, so here I'll say const API base URL, because we'll need this to call the API. This is in the description in the video description. And here let's initialize our posts object as an empty array at the beginning. So, now let's call this on mount method and say on mount, and this takes a callback that happens when the component is mounted, and this is going to reach for for this is going to hit the API. So I'm going to make it an async callback. So here I'll say async. Oops. And here it's going to be an arrow function. And inside of here I'll say const result or res equals await fetch. I'm going to use fetch API. And I'm going to give it the API base URL plus slash posts like this. This is the route that gives us all the posts. And here we'll say posts our So this variable right here equals await await res. Oops. json like this. So the way fetch works is that you need to as well return response.json and this returns a promise with the data that's got from that request. And now when we assign a value to post our component will actually re-render. Now let's use these posts to display them on the template. Here I want to loop through these posts. So first I want to do a conditional cuz if we're still fetching the post I want to show loading posts. So here we'll open curly braces and do hash if and this is felt template syntax and we'll say posts.length equals zero. So if the length of posts equals zero that means we haven't got posts yet. So I'll do a header three and say loading posts dot dot dot. So you can put a spinner here if you want. And here we'll say colon else. So else if we have any posts, if it's not zero the length, we want to loop through them. So we'll open another JavaScript expression and say hash each or just an expression and say posts as post like this. This is kind of similar to PHP if you've worked with it this syntax post as post. So, here we'll say uh div.col .s6. This is materialize stuff. I want each post to take half the width of the the viewport of all like the width of the container. And here I'm going to put a card, so .card. And inside the card we need card content. Uh so, .card content. And inside that div I'm going to start with the title, so we'll say paragraph p.card title. And inside of here we'll do curly braces to put dynamic values. And now that we have access to this post, we can use what comes inside of the post. By the way, you can call credit this API on Postman or something and you'll find that posts have a body, a created at, a user ID, and and a title. So, here we'll need to say the title because this is the card title. So, we'll say post.title like this. Uh I want to show as well the created at. So, here we'll say p and I'll say curly brace post.created at like this. And let's put the body of the post, so here paragraph another one and say post.body like this. Here we need to close the each tag. So, here we'll say we open curly braces and we say /each and this will close that tag. And here we need to close as well this if statement. So, here here we'll say curly brace /if like this. All right, let's save this and see what this looks like. Let's go to our app and there we go. We're getting three posts which are all the posts that are in the database right now. If we reload, we'll see loading posts for like a brief second before the actual posts load. All right, so let's add the two buttons for editing and deleting and I want to style this a bit to make it look better than that. All right, let's go back. So, underneath this div, this card content div, I'm going to add dot card action. And here we'll have two links. So, one anchor tag with doesn't go anywhere. And this is going to be the edit post. So, here we'll say edit. And I'm just going to copy this and add another one, which is going to be delete. And I'll give this a class to to later style it. So, I'll give it a class of delete uh dash btn. Uh let's save. Let's see what these look like. All right, they look okay. And uh I want to style this uh delete button. So, here let's open up a style tag. And um by the way, these styles are scoped to these components. So, any style I write here will not go to any other component even if the component is inside of here. So, here we'll style the um the delete button. So, I'll say dot uh delete uh dash btn. I just want to give it like a a color of uh red. And uh I'm going to give this important for it to apply. And I want to style the card's title. So, I'll say dot card dot card content dot card title to target that. And I just want to the this this um syntax completion is a bit weird with this uh extension right now. But I guess that will be fixed in the near future cuz this is fairly new. So, here we'll say uh margin bottom I want to give it a margin bottom with zero. And I want to style as well the uh this date, the created at. So, I'm going to give it a class. Where is this? Right here. I'm going to give it a class of time stamp. And here we'll say So, we can just copy this. Instead of card title, this will be p. uh time stamp. And I'll just Oops. I'll just give this a color of like a gray like hash 999 and I'll give it some margin bottom so it separates itself from the body. So margin bottom of 10 pixels. All right, let's see what this looks like. All right, it looks better. So let's go back. Now we can make these into a component by itself but we're going to make some other components so I'll show you how to make components anyways. Here let's give these two buttons a callback like like a function that will be triggered when they're clicked and for this we're going to use the on directive. So here we'll say on colon and now we give the type of the event. So here we're going to give the event click and then say equal and open an expression and here we can pass a function that will be triggered once this button is clicked. So here I'll pass a callback cuz otherwise it will trigger it right when the the component is rendered and here I'll say edit post and pass it this post. And here as well we're going to give a the delete another event so here I'll say on colon click equals and here I'll give a callback to delete post and I'm going to pass the post ID. And we're going to implement these later but for now I'm just going to have them print something to the console. Okay, there's a mistake here. All right, like this. Let's go up here in the script tag let's create these two functions. So here we'll have edit Oops. Edit post will take a post and for now it's just going to console log it so we'll just console log post like this. Actually I need to use the keyword function. Let's create the the delete post as well. So function delete post will take an ID and for now I'm just going to say deleting post with ID and just concatenate that ID. Let's save. Let's see if these are running properly. So, let's open the developer tools, the console. And I'm going to put this side by side. And here if I press edit on this, actually it doesn't do anything. Let's go back. Okay, I made a mistake here. Let's save that. Let's go back to our app. Refresh. And here if I click edit, there we go. It's printing that post that we clicked on edit. And if I click delete, it says deleting post with ID something something which is the ID of this post. All right, cool. So, let's go back to our app. Let's create the form that we will use to submit a post to the server. So, on top of this row, I'm going to add another row at the top here and say row. And here I'm going to have it take half the width. So, I'll say dot call dot S6 tab. And inside of here, don't worry about that pretty old format it. I'm going to put the form, but I'm not going to put the whole form here. I'm going to just put the component and make it into into its own component. So, here I'll say post form. And then just leave it like this. And let's import that and then create it. So, here I'll say import post form from I'm going to create a folder call it components. And actually here we're inside pages, so we have to go back one level and then say components /postform.svelte. Like this. And here let's create this folder. components And inside of components I'm going to create the postform.svelte. So, here we'll write our form. We'll say oops, we'll say form. Don't know why form doesn't work. I'll just say form like this. And this will have an submit event, so we'll say on and the the event will be submit. Submit. Oops, submit equals and we will call a function that we'll call on submit like this. And let's close this form. And inside the form we'll have a div with the class input field and this is materialize stuff just to style it with materialize. Here we'll have two fields, one field for the title and one for the body. So here we'll put a label for title and it will say title like this. And here we'll put the input for that title of type text. And this here, what we need to do is we need to bind the value of this input with a value in our component with a variable. So Svelte has two-way binding meaning that we can use a directive called bind and then give say colon value equals. Now we want to give the name of the value that we're going to use which we'll call title which we haven't created yet but we will. So now whenever title this input changes, it will change title in our component and if title as well changes, the value of the input will change. This is what two-way binding means. So let's copy this entire input field and paste it here. And here we'll change this is a label for body and this will say body and this variable here as well will be called body. And let's add a submit button. So we say button with type submit. So colon submit and click tab and we'll give it some classes to style it with materialize CSS styling. We'll say waves effect waves light and btn as well and this button will say add cuz it adds a post. And here let's open a script tag. And I don't know if it's the Svelte extension or if it's prettier. It's probably the Svelte extension but you can put the script tag underneath the the markup and if you save, the script tag will go up to the top which is pretty cool. And the same thing with style because um um logically style should be before before the HTML because that's how cascading style sheets work. And if I save, the style tag will go up um above the template, which is pretty cool. All right, so let's go to the script. So here we'll declare these two variables, the title and the body. So we'll say let title equals uh an empty string and let body equals an empty string. All right, now we don't have any red squiggly lines, but we have this green squiggly line telling us that it's not the on submit is not defined. So let's fix that. Here we'll say function on submit and we'll say it takes an event and of course first thing we do we say event.prevent default like this. I don't know why I added that underscore. Prevent default like that. And here I'll do like a very basic validation and say if title .trim equals I don't know why it's replacing these functions. Uh equals an empty string or body .trim I don't know why it's changing these. Trim is a a JavaScript function. This is a bit weird, but uh let's bear with it. Uh if if any of these two is an empty string then we just return because we don't want to submit this cuz this is invalid data. Uh you can of course show some validation errors, but uh that's kind of JavaScript. I want to focus on Svelte more for this tutorial. So if not, we have these fields then let's form this post and send it to our server. So here we'll say const new post is uh an object which will have a title of the value of title, so we can just say title like this and body like this. Now let's bring our base URL from here. Let's copy this and uh put it right here. And now we need to send a request a post request to our database to persist this post. So, we'll say um actually we'll use async await. So, here we can make this an async function. We add the async keyword. And here we'll say const uh response equals await fetch. We do backticks. And here we'll say uh dollar sign curly brace API base URL. And uh we concatenate {slash} post because this is the route that we post to. And here we'll say comma, and we pass some options uh including the method. So, the method will be uh post. So, method post like this. And the body of the request will be JSON.stringify or actually stringify like this. Stringify. And we pass it the new post uh that we just created. So, now when we get that data, now we need to get the post from that data. So, we'll say uh const post equals await re- res.json. Oops. I don't know why it's changing these variables. It's a bit annoying. It's very strange. Okay, let's save all files. Uh let's look at our app. Uh we broke it. On submit is not defined. Okay. Okay, cuz here this is a capital S. On submit like this. All right. So, we get our form. And uh if we type anything here, so let's say post from Svelte. If we leave this empty, it shouldn't submit anything, and it doesn't. And if we type some gibberish here, we click add. I think it does send a request. If we look at network, post. All right. So, it sends a request, and the status code is 201. So, it's been created. Of course, we're not adding any code to show it here, but if we refresh, we see that that post has indeed been posted. Uh I want to do something here. I want to have a loading boolean and when we send a post, it will actually show us a spinner bar that that indicates that we're actually communicating to a back end. So here I'll create another variable, call it loading. So let loading equals initially it'll be false. And here when we submit the form, if it's valid, then first thing we want to do, we want to set the loading to true. So we'll say loading equals true. This is as simple as that. And just the fact that we change this variable and this variable is used in the markup, just the fact that we reassign it to a different value, it's actually going to re-render our our markup. So we set the loading to true and then we communicate to our server and once everything is done, we set the loading back to false. So we say loading um equals false false like this. Now in our markup, we let's cut this form. And here let's do curly braces uh hash uh if and we'll say if not loading, then we want to show this form. And then here let's say else. So colon else. And here else, if we're loading, let's do dot progress. And this is materialize CSS stuff. And here we'll say dot indeterminate. And this will give us like um an indeterminate uh loading bar or progress bar. So here we'll uh finish close that if statement. We'll say slash if like this and let's save. Let's go back to our app. Now if we put some stuff here and we hit add, there we go. We see that loading bar for a second and then it goes away once the loading stops. Uh let's actually make that loading bar go a bit in the middle and give this some padding so that it looks a bit better. So let's go back here. And what's cool about Svelte is that we don't have to give this a class and style it. Just because this is in just in this component, we can just say form and then style style this form and none of the other forms in any other page will get the style because this is scoped to this component. So, here I'm just going to give it some margin on all sides of a 50 pixels. And here we'll say I want to style the progress bar, so I'll say progress and I'll give this a margin top and bottom of a 100 pixels and left and right of zero. So, let's save this. Let's look at our app. So, all right, cool. The form looks much better now and if we submit something else, that bar is in the middle here. All right. Let's work on actually adding this post to our post list. Now, if By the way, of course, I'm getting all of this from the documentation. Svelte has some really cool documentation. If you go to examples, you can even fiddle with the code and change the examples and how they work. And there is this thing right here called event forwarding, which is what we're going to use to communicate between the inner and the outer components that we have. So, if you see here, it actually dispatches an event from inside of a component that's nested inside this component and then based on that event, the outer component will perform some action. So, let's copy this import from here, this create event dispatcher. Let's copy that. Actually, let's copy both of these cuz we need that. Let's go here. Let's paste this at the top. And uh yeah, I can keep that there. And then after we get the post, we want to dispatch this event. So, let's dispatch an event and we just say dispatch like this and let's call this event post created and we can pass a payload. So, the payload would actually be this post. Now, we can listen to this event on any other component and then catch that and then get this payload and do whatever we want with it. So, where we want it, we want it in the home page. So, here in the home page, I'm going to go down here where we uh add our form, and I'm going to listen to that event. So, I'll say on, and here I put the name of our custom event and say post created. So, on this event, we're going to call a function. I'm going to call this add post. Simple as that. Let's go up here and create this add post. Now, we want to create a function that adds that post that we got to this post array that we have. So, here I'll say function add post. And if you look at the documentation, you will see that uh the event uh right here. Actually, if we look at app.svelte, the event has this property detail, which holds our uh payload. So, here in our add post, we will we can destructure it straight away. So, we will destructure detail, and we can do colon and give it another name because it's um cuz it makes more sense to call it post here instead of detail because it's actually a post. So, here now that we have that data, we just want to add it to our posts. So, we can simply say posts equals, and we do an array, and we want to put it at the top, so we'll say post {comma} and then we spread our existing posts like this. Now, uh be careful with this. You don't want to do uh posts.push or unshift because when you do that, you're not assigning a new value. You're changing the variable, but you're not assigning a new value. So, that wouldn't actually cause a re-render. You want to do post equal, and then you actually add your data. So, let's save all files, and let's look at our app and see if this is working. So, it's right here. Let's refresh just in case, and we can say post to be added uh add this post, and we click uh enter, and there we go. Our post is actually added to our front end. But, our form is not resetting, so let's fix that. Let's go here. So, in our form, uh when we submit that and we dispatch the event, we can simply say um title equals uh an empty string and body as well. Or we can say title equals body equals empty string. So, we reset both of them. All right, let's look at our app. Reload just in case and let's put some gibberish. Uh that gets added and the fields are reset. Sweet. Let's now implement this uh delete button. I mean, uh give it some actual functionality. So, let's go here in the home. Uh so, we have or we already uh created this delete post uh function, but it doesn't do anything. So, here we will say fetch. And the way our API works, we want to send uh to the URL {slash} post {slash} uh the ID of that post and we want to send it as a delete request. So, here we'll want to concatenate our We'll say uh curly brace uh dollar sign curly brace API base URL and close that curly braces {slash} {slash} post {slash} and then concatenate the ID as well. And then here we want to pass some options. And in the options, we only want to say that the method is a delete method. And here we can use the the the dot then syntax. Uh and then here we say response. And by the way, uh just because I'm using async there and the dot then here, I wouldn't do it in a project. I'm just showing you that there are multiple ways of doing this. In one of my projects, I will still stick to one way of doing things to maintain readability. So, here with the response, want to return res.json like this and then chain another dot then where we get uh actually, we don't need any of the result that's returned. Nothing gets returned. So, we we just want to actually remove that post from our front end. So, here we'll say posts equals and we'll say post.filter to remove that post. And our filter will be post where post. Oh, actually post. .id does not equal this ID, which will now remove all the posts that don't have this ID. Uh I mean, keep just the posts that don't have this ID, meaning that it will only remove that post. So, let's save that. Let's look at our app. Let's reload just in case. If we delete this, it actually goes away. If we delete this, it goes away. Let's add a uh pop-up like a confirm pop-up that, you know, just in case people don't delete everything by mistake. So, let's copy all of this. And here we'll say uh if confirm, and the confirm will say, "Are you sure?" So, if they click okay on that, we actually want to send that post that I mean that request. And now if we click delete, it asks us, "Are you sure?" If we click okay, it actually deletes it. All right, let's now work on the edit button. So, let's go here. So, this is called from the post form. Actually, no, from the home. So, what we want to do now is that we want to when we click on edit, we want to pass the details of that post down to this form and then populate the fields of that form with those details. So, here when we um edit a post, we're going we're going to set a new property. Here I'll call it um editing post. And initially this will be uh we'll have a body uh that's an empty string, a title that's an empty string, and an ID that's null. Cuz the way our API works, when we want to edit a post, we want to send the body and the title and the ID as well to know which uh post to edit on the database. So, now we want to when we edit post, we want to set this editing post to this post that we clicked to edit. So, we'll say editing um post equals this post that we got here. Simple as that, but we want to pass this editing post to the to the post form as a prop. We can do post editing post equals editing post like this. But when we save, it's going to change it to like some really nice minimal syntax that I've been wishing that it would happen on React a while ago, which is just doing curly braces editing post, which was which is going to give that prop name and that value to our post form as well. Now, we want to use that in this component and display those details. So, let's go up here. Now, what we can do, we can say title equals editing post.title up here. So, we can say let title equals editing post. title And do the same thing for body. Actually, I haven't tested this. I don't think it will update once we Yeah, it won't update. Actually, there's a problem. Says editing post is not defined. Okay, I know why because we need to declare editing post as a prop that we can that we can get from outside. So, we need to say export let remember like that that was on the app as well for the property name. So, we can need to say the same thing for editing post. I'm going to say export let editing post. This will tell this component that we can receive this as a prop. So, let's save. Now, if we look at our app, so that's fine. But the problem now set to an empty string, but if we click edit, it will not change because it's not tracking any changes. The way we fix that, we can just use this syntax. We can say dollar colon and we can do the same thing for body here. And this what will it will tell our component will be like, "Look, we will assign this value, but whenever editing post.title changes, then assign that value again to title. So, this is reactive to editing post. So, if we save this, now that should fix it. So, here if we click edit, there we go. We get the details from this component, I mean, from this post to our form right here. So, if we click here, we get those, and we click here, we get those. That's pretty cool. Uh I want to as well change the button from add to update once we are in actually editing mode. So, there's a simple trick. So, right here, once our editing post has some value, when we click here, it will also have an ID, cuz by default it's null. So, we can use that as a conditional. So, down here, instead of just add, we will put an expression, so we'll do curly braces, and we'll say editing post.id {question mark}. So, if this is not null, uh we will say update. Else, if this is null, that means we're in add or we're in creating mode, we'll say add. Let's save that. Let's look at our app. So, by default it says add when the ID is null, but when we click on edit, it becomes update. Cool. Let's now add the logic for actually reaching to our server and updating this post. All right, let's go back. So, this will happen through the on submit as well, of course, but now what we need to do, we need to add a new thing here. We will say, because if we have an ID, we will actually send a post request to API/post/the ID, and then it will be a put request to edit that post with that ID. So, here we can just say condition, and we'll say if editing post.id, so if it's not null, then we're going to actually update a post. We're going to form a URL. Let's say actually here we can say, actually we need to declare these outside because we will need them later, so we'll say let, we'll create these two variables, URL and method as well because the method could be either a post or a put. So here we'll say URL equals, let's do backticks, and the form our URL would be API base URL. Uh like this, {slash} post {slash} this ID. So we can do dollar sign curly brace, and we can just copy and paste that inside. So that's our URL, and of course now the method will be uh put because we're in edit mode. So we'll say put like this. Else, if the ID is null, that means we're trying to create a post. So the URL will be um backticks, and we'll say curly brace, and we'll say API base URL {slash} post. And the method will be post. And now we can say uh we can send the same request, but instead we can send it to URL because this uh could be different, and the method is just method, so we can just omit this and send the same body. So here let's save, and this should work. So let's look at our app. Let's put these side by side, and let's look at our network tab. Let's clear that. And now if we just I'm going to refresh just in case. Now if we just submit a post, but I can't type in these fields. Uh Okay, I can't type in these fields because I didn't change these values. Now these values should actually be editing from editing post. So here I'll say editing post.title and .body. This should fix that. Let's go back. All right, now I can post. I mean, I can type. All right. So here if I just send this this should be a post request. Okay, here it says URL is not defined. See that. Okay, this is URL. I don't know why the auto correct is changing my variable names. That's very weird. I hope they fix this extension. All right, now it should work. If I put some gibberish and click add, and if I look at the network tab, it sent a post request to {slash} post. But now if I click on edit the same one and give it just like a bunch of V's like this and click update, and if we go back, it's right uh right here. Okay, so this is the a put request and it's gone successfully. But of course the problem now it's actually added it because we didn't change the logic to add post in the home component. So let's do that. So let's go to the home component. So here in add post we want to check if we already have that post, then we just want to edit it. We just want to replace it. So we'll do if posts.find post where post.id equals this post that we got id. So if this is truthy, that means we already have this post. That means this post was probably being edited. So we just want to find the index of it and replace it in our existing posts. So we'll say const index equals posts.find index and we want to find the index of post where post.id is the same condition that equals this post.id. Now that we have this index, we need to declare a new array and say let posts updated equal posts. So we're just making a copy of it right now that we will assign later. And now we want to edit this post updated. So post updated.splice and we remove starting from the index, we remove only one and then we replace it with this post. Now we can simply say posts, so our posts equals posts updated, which will re-render. Uh else uh else we just do this. All right, let's save and let's see what this looks like. So now if we want to edit all if we want to edit this one as well and change it to like like all x's like this, click update, there we go, it changes to all x's and it doesn't add a new one. Let's reset the form. Now the form should be reset from here. We can't reset it from inside and this title and body don't exist anymore, so we can remove that. And here we can just assign it again to this. So we can just copy that and after either of these happen, we'll just do this, paste this here. All right, let's go back. Now let's edit these from v's to w's like this and we click update and the form resets. Cool. Let's add the post limiter that limits the number of posts right here. So let's go back here. Let's go down to the markup and after the form here, we're going to add a column with the width s3. And here I'll put some text, say limit number of posts. And after this I'll put an input, input of type number and this will have no name. I'll bind it to some value and I'll call this value post limit and it won't have any ID. Close that tag. And after this it will have a button and this will have a click event, so on colon click I want to call the set limit. Uh let's give it some materialize classes, waves effect and waves light and btn. Let's close that button and it will say set. All right, let's create this method, this function and this post limit and this set limit. So we go up here. Say let post limit. And uh we'll create that function set limit. Let's go down here and say function set limit. We'll uh send a fetch. Um we'll say fetch to send a request. And then we can just copy this. So, to the base URL URL/posts/that number. So, we'll put the post limit right here. And it's a get request, and we don't we need to say anything. We just chain then. And when we get a result, uh we want to return res.json. And here we'll chain another then. And uh we will get the posts. And here we'll say Actually, we going to want to give it a different name to not conflict with the post that we already have. And we'll say post equal equals posts uh data like this. All right, let's save everything. Uh let's look at our app. Uh let's give it a default value so it doesn't look empty like that. And let's give it like some margin on all sides. I'm just going to give it some inline styling. Uh right, where is it? So, it's this. I'm just going to say style equals margin 50 pixels like that. And we want to give this post limit a default value of six. All right, let's save. All right, it looks much better. Now, if we want only two posts, we click set. It doesn't work. It's cuz reference posts Oh, I made a typo. My bad. So, right here, this is posts, not psots. Let's save. Let's go here. Want to get two. We set, we get two. Three, we get three. If we put a massive number, we get all of them. All right, cool. Actually, I forgot to show you something. Let's actually build this app to see the bundle size of it. So, here we're going to stop this development server. What is it? NPM run build? Yeah, it's NPM run build. So, I'll say NPM run build. Hit enter. Okay, it's built. Let's open this. Uh open reveal in explorer. So, we'll look at the public. The bundle is 196. Okay. That's unfair. Cuz that's most of it is coming from this materialize JS. All right, I'm going to just comment that for now and build it. So, NPM run build. Just to show you the actual bundle size of Svelte itself. All right, cool. So, if we look at public now, it's 21 kilobytes, which is absurdly low. And 10 kilobytes or 11 kilobytes of this is actually coming from Svelte routing. So, Svelte itself is only 10 kilobytes. Um I mean, this app itself, of course, there's no Svelte code inside of this bundle. It's just some JavaScript instructions with our own code, which is um This is insanely small and uh very efficient. So, yeah, I hope this gave you like a good start with Svelte. I hope that you're excited about Svelte and you want to use it and learn more about it. Thank you very much and I hope to see you soon. Bye.

Original Description

Learn Svelte in this full tutorial for beginners. You will build your first Svelte app that uses multiple routes, handles forms and consumes a full CRUD API. Svelte is a radical new approach to building user interfaces. It is a framework that really isn't a framework. Whereas traditional frameworks like React and Vue do the bulk of their work in the browser, Svelte shifts that work into a compile step that happens when you build your app. 🔗 Full Code: https://github.com/hidjou/classsed-svelte-tutorial 🔗 API Base URL: https://ndb99xkpdk.execute-api.eu-west-2.amazonaws.com/dev 🔗 Rich Harris talk: https://www.youtube.com/watch?v=AdNJ3fydeao 🎥 Course created by Classsed. Check out their YouTube channel: https://www.youtube.com/classsed 🔗 Classsed Discord: https://discord.gg/GUuKyQW 🔗 Classsed Patreon: https://www.patreon.com/classsed ❤️ Support for this channel comes from our friends at Scrimba – the coding platform that's reinvented interactive learning: https://scrimba.com/freecodecamp -- Learn to code for free and get a developer job: https://www.freecodecamp.org Read hundreds of articles on programming: https://www.freecodecamp.org/news
Watch on YouTube ↗ (saves to browser)
Sign in to unlock AI tutor explanation · ⚡30

Playlist

Uploads from freeCodeCamp.org · freeCodeCamp.org · 0 of 60

← Previous Next →
1 React: Production Server Setup Part 2 - Live Coding with Jesse
React: Production Server Setup Part 2 - Live Coding with Jesse
freeCodeCamp.org
2 cookies vs localStorage vs sessionStorage - Beau teaches JavaScript
cookies vs localStorage vs sessionStorage - Beau teaches JavaScript
freeCodeCamp.org
3 Browser history tutorial - Beau teaches JavaScript
Browser history tutorial - Beau teaches JavaScript
freeCodeCamp.org
4 Graph Data Structure Intro (inc. adjacency list, adjacency matrix, incidence matrix)
Graph Data Structure Intro (inc. adjacency list, adjacency matrix, incidence matrix)
freeCodeCamp.org
5 React: Parameterized Routing with Next.js - Live Coding with Jesse
React: Parameterized Routing with Next.js - Live Coding with Jesse
freeCodeCamp.org
6 React: Dealing with jQuery Issues - Live Coding with Jesse
React: Dealing with jQuery Issues - Live Coding with Jesse
freeCodeCamp.org
7 setInterval and setTimeout: timing events - Beau teaches JavaScript
setInterval and setTimeout: timing events - Beau teaches JavaScript
freeCodeCamp.org
8 Browser and Device Testing - Live Coding with Jesse
Browser and Device Testing - Live Coding with Jesse
freeCodeCamp.org
9 Last Minute Updates - Live Coding with Jesse
Last Minute Updates - Live Coding with Jesse
freeCodeCamp.org
10 Post Launch Updates - Live Coding with Jesse
Post Launch Updates - Live Coding with Jesse
freeCodeCamp.org
11 React: Setting Up Google Analytics - Live Coding with Jesse
React: Setting Up Google Analytics - Live Coding with Jesse
freeCodeCamp.org
12 React: Masonry Layout - Live Coding with Jesse
React: Masonry Layout - Live Coding with Jesse
freeCodeCamp.org
13 Load Balancing Digital Ocean Droplets - Live Coding with Jesse
Load Balancing Digital Ocean Droplets - Live Coding with Jesse
freeCodeCamp.org
14 try, catch, finally, throw - error handling in JavaScript
try, catch, finally, throw - error handling in JavaScript
freeCodeCamp.org
15 Load Balancing: SSL Passthrough Setup - Live Coding with Jesse
Load Balancing: SSL Passthrough Setup - Live Coding with Jesse
freeCodeCamp.org
16 Graphs: breadth-first search - Beau teaches JavaScript
Graphs: breadth-first search - Beau teaches JavaScript
freeCodeCamp.org
17 React: Masonry Layout Part 2 - Live Coding with Jesse
React: Masonry Layout Part 2 - Live Coding with Jesse
freeCodeCamp.org
18 React: WordPress API Live Search - Live Coding with Jesse
React: WordPress API Live Search - Live Coding with Jesse
freeCodeCamp.org
19 Creating WordPress Custom Post Types - Live Coding With Jesse
Creating WordPress Custom Post Types - Live Coding With Jesse
freeCodeCamp.org
20 Dates - Beau teaches JavaScript
Dates - Beau teaches JavaScript
freeCodeCamp.org
21 Miscellaneous Front End Updates - Live Coding with Jesse
Miscellaneous Front End Updates - Live Coding with Jesse
freeCodeCamp.org
22 Merging a Pull Request from GitHub - Live Coding with Jesse
Merging a Pull Request from GitHub - Live Coding with Jesse
freeCodeCamp.org
23 React + Prettier + Standard JS - Live Coding with Jesse
React + Prettier + Standard JS - Live Coding with Jesse
freeCodeCamp.org
24 React: Sortable Responsive Table - Live Coding with Jesse
React: Sortable Responsive Table - Live Coding with Jesse
freeCodeCamp.org
25 Geolocation Sorting by Distance - Live Coding with Jesse
Geolocation Sorting by Distance - Live Coding with Jesse
freeCodeCamp.org
26 Tradeoff Matrix - Agile Software Development
Tradeoff Matrix - Agile Software Development
freeCodeCamp.org
27 The Definition of Ready - Agile Software Development
The Definition of Ready - Agile Software Development
freeCodeCamp.org
28 Getting first React job without experience - Ask Preethi
Getting first React job without experience - Ask Preethi
freeCodeCamp.org
29 React: Google Analytics Click Tracking - Live Coding with Jesse
React: Google Analytics Click Tracking - Live Coding with Jesse
freeCodeCamp.org
30 Submitting a PR to an Open Source Project - Live Coding with Jesse
Submitting a PR to an Open Source Project - Live Coding with Jesse
freeCodeCamp.org
31 Should I go back to school to get CS degree? - Ask Preethi
Should I go back to school to get CS degree? - Ask Preethi
freeCodeCamp.org
32 Hero Section CSS Changes - Live Coding with Jesse
Hero Section CSS Changes - Live Coding with Jesse
freeCodeCamp.org
33 Working Agreement - Agile Software Development
Working Agreement - Agile Software Development
freeCodeCamp.org
34 A day at Pennybox with Co-Founder Reji Eapen
A day at Pennybox with Co-Founder Reji Eapen
freeCodeCamp.org
35 React: Sorting and Filtering Data - Live Coding with Jesse
React: Sorting and Filtering Data - Live Coding with Jesse
freeCodeCamp.org
36 React: Sorting and Filtering Data Part 2 - Live Coding with Jesse
React: Sorting and Filtering Data Part 2 - Live Coding with Jesse
freeCodeCamp.org
37 React: Building a New UI - Live Coding with Jesse
React: Building a New UI - Live Coding with Jesse
freeCodeCamp.org
38 Definition of Done - Agile Software Development
Definition of Done - Agile Software Development
freeCodeCamp.org
39 Getting started with jQuery (tutorial) - Beau teaches JavaScript
Getting started with jQuery (tutorial) - Beau teaches JavaScript
freeCodeCamp.org
40 Making a React Blog with WordPress Content - Live Coding with Jesse
Making a React Blog with WordPress Content - Live Coding with Jesse
freeCodeCamp.org
41 React, NextJS, CSS - Live Coding with Jesse
React, NextJS, CSS - Live Coding with Jesse
freeCodeCamp.org
42 jQuery events - Beau teaches JavaScript
jQuery events - Beau teaches JavaScript
freeCodeCamp.org
43 React/NextJS Routing and WordPress API Custom Types - Live Coding with Jesse
React/NextJS Routing and WordPress API Custom Types - Live Coding with Jesse
freeCodeCamp.org
44 React: Working with API Data - Live Coding with Jesse
React: Working with API Data - Live Coding with Jesse
freeCodeCamp.org
45 React: Refactoring Components - Live Streaming with Jesse
React: Refactoring Components - Live Streaming with Jesse
freeCodeCamp.org
46 jQuery effects - Beau teaches JavaScript
jQuery effects - Beau teaches JavaScript
freeCodeCamp.org
47 More React Refactoring - Live Coding with Jesse
More React Refactoring - Live Coding with Jesse
freeCodeCamp.org
48 animate in jQuery - Beau teaches JavaScript
animate in jQuery - Beau teaches JavaScript
freeCodeCamp.org
49 "Finishing" My React Site - Live Coding with Jesse
"Finishing" My React Site - Live Coding with Jesse
freeCodeCamp.org
50 Starting a New React Project (P2D1) - Live Coding with Jesse
Starting a New React Project (P2D1) - Live Coding with Jesse
freeCodeCamp.org
51 React Project 2 Day 2: Learning Material UI - Live Coding with Jesse
React Project 2 Day 2: Learning Material UI - Live Coding with Jesse
freeCodeCamp.org
52 The Agile Manifesto - Agile Software Development
The Agile Manifesto - Agile Software Development
freeCodeCamp.org
53 jQuery: get and set with http, text, val, and attr - Beau teaches JavaScript
jQuery: get and set with http, text, val, and attr - Beau teaches JavaScript
freeCodeCamp.org
54 React Project 2 Day 3 - Live Coding with Jesse
React Project 2 Day 3 - Live Coding with Jesse
freeCodeCamp.org
55 The INVEST approach to product backlog items
The INVEST approach to product backlog items
freeCodeCamp.org
56 React Project 2 Day 4 - Live Coding with Jesse
React Project 2 Day 4 - Live Coding with Jesse
freeCodeCamp.org
57 Chickens and Pigs - Agile Software Development
Chickens and Pigs - Agile Software Development
freeCodeCamp.org
58 React Project 2 Day 5 - Live Coding with Jesse
React Project 2 Day 5 - Live Coding with Jesse
freeCodeCamp.org
59 jQuery: add and remove DOM elements - Beau teaches JavaScript
jQuery: add and remove DOM elements - Beau teaches JavaScript
freeCodeCamp.org
60 React Project 2 Day 6 - Live Coding with Jesse
React Project 2 Day 6 - Live Coding with Jesse
freeCodeCamp.org

Related Reads

📰
Why Vanilla JS? In the article below, I am sharing my story of building SaaS product in vanilla js and explaining why I decided to go with this approach. https://guseyn.com/html/posts/why-vanilla-js.html
Learn why choosing Vanilla JS can be a great approach for building SaaS products and how it can simplify development
Dev.to · Guseyn Ismayylov
📰
How to Create a Cursor Tail Using HTML, CSS, and JavaScript
Learn to create a colorful cursor tail using HTML, CSS, and JavaScript for a unique user interface effect
Medium · JavaScript
📰
I built a landing page with Three.js, vanilla JS, and zero frameworks — here's what I learned
Learn how to build a landing page with Three.js and vanilla JS without relying on frameworks, and discover the key takeaways from this project
Dev.to · Ayush Shekhar
📰
Part 1: Why I Rarely Use useEffect Anymore (and what I use instead)
Learn why useEffect is not always the best choice in React and discover alternative solutions
Dev.to · Alejandro
Up next
How To Build A Twitter Clone - React Next JS - Appwrite Crash Course
Adrian Twarog
Watch →