Playing
06. Practical: Infinite Scrolling

Transcript

00:00
Let's combine two new inertia features to build out a really easy infinite scroll in our application.
00:07
It's worth noting that in the future we're expecting an infinite scroll component in itself within inertia, so by the time you've watched this, that might already be available. If it's not, we can go ahead and build it out ourselves with not much trouble. Okay, so let's get started on creating out a model that we're going to use for this.
00:24
We're going to go ahead and use an article as an example. We'll create a migration of factory and a seeder alongside of this. Okay, let's open up the create articles table and let's just fill this in with some data. So of course we're going to have a title in here, so let's go ahead and add in a title
00:41
and we'll go ahead and add in a teaser to this as well and I think that's just about it for now. Okay, so let's, before we migrate this, open up our article factory and let's go ahead and define out how we want to fake this data. So let's say title and we'll say fake sentence and let's give that six words
01:01
and we'll do the same thing for the teaser here and just bump that up to maybe 30. Okay, let's go ahead and migrate what we have here and now that we've done this, we want to be able to seed the database. So if we open up the article seeder, we want to do this but we want these in a very specific order.
01:20
So usually to seed data in a particular order, I'll go ahead and use a sequence within a factory. So we can use our article factory, we can go ahead and create that out, but in between that choose how many records we want here.
01:35
Let's go ahead and bump this up quite high to say a thousand, but we want to make sure that the created at date increments here. So a little tip that I use is to create out a sequence and then use the index that we get back in the sequence within this factory
01:52
to go ahead and increment the date. So to do this, we just want to go ahead and return and adjust the created at date and what we'll do is take the current date and time, but modify it for every single record that we create.
02:07
So we can add on some days to this using the sequence index. By doing this, that's going to go ahead and increment that created at date and then we're going to have them in a nice natural order. Okay, so now that we've done this, let's go ahead and run dbseed here
02:21
and let's run this for the article seeder. Okay, so if we open up our database now and take a look at articles, you can see that for the created at date, the day increments for each one. So this is going to make it much easier to see what we're doing
02:33
when we're outputting a list of these articles. Okay, so let's build out a specific articles page for this. So let's go and hit this in the browser and we'll go ahead and fill this in. Okay, so we'll create our controller just to keep things nice and tidy.
02:47
So let's create out an article controller here and we'll go over to our web root and we'll just define this out anywhere. So let's go ahead and just set this to slash articles, reference that article controller and we'll just make this invocable.
03:01
Okay, if we open up our article controller, let's create out that invoke magic method and let's go ahead and just return an inertia response here and we'll render out a page called articles. And of course, we'll pass all of them articles down to the view.
03:18
We'll modify this slightly in a minute. So we're just going to say article latest and get. Okay, so we can go ahead and create this component now. So let's go into resources, JS and pages
03:30
and let's create our new view component in here called articles. Let's go ahead and add that and we'll just start by adding a define props in here. Taking in our articles, which is going to be an array and then we'll just dump them out on the page for now.
03:48
In fact, let's copy over the dashboard template. That probably makes a lot more sense and let's just slightly modify this. So define props, articles going to be an array and we'll go ahead and just dump them somewhere here.
04:02
Let's change the title of this page as well and the header up here and let's do the same and just dump all of the articles. Okay, great. So we've got a thousand articles in here. Let's go through and just make these look a little bit better first of all.
04:17
So we'll start with a div wrapper in here and we'll say v for article in articles. Let's go ahead and key this by the article ID and then let's just add in a wrapper inside of here and let's do this slightly differently actually.
04:32
Let's go ahead and just grab all of this and we'll wrap each article in this container. So just so we have something to play with like this and we'll pull this in and we'll just dump each of the articles out in here just so we've got as much space to work with as possible
04:53
and let's go ahead and space these out on the y-axis by three. There we go. Just so we've got enough room to scroll. Okay, let's just fill in some really basic data about this. So we'll create an h2 for each of these for the article title
05:07
and then we'll create a paragraph out for the article teaser in here as well and we'll just start these up really quickly as well. So we'll set the text to extra large and font to semi-bold and I think that will just about do.
05:23
Okay, so we've got a thousand articles on the page at the moment which is obviously not great. So where do we start here? So before we had the ability to merge in props or use when visible
05:34
we would probably do something like this. We would paginate this data out. We would go over to our articles and update this to articles.data but we would probably take this data and store it locally up here in a ref
05:47
and then we would go ahead and request the next page and then take the data from here and push it on. We've covered this before on CodeCourse but we want to make this a lot more effortless
05:57
now that we have these two features. Okay, so I've paginated this. The problem is we can't use merge for a paginate object. We don't have the ability at the moment at least to deep merge.
06:11
So what we're going to do is we're going to take the paginated articles so let's go ahead and call them articles up here and we're going to go ahead and for the articles data we're going to explicitly extract out the items
06:23
but make these mergeable. So let's use merge in here. We'll give this a short closure and from articles we'll extract out the items.
06:32
So we'll still only get 10 here because we're paginating up here but what we can also then do is separately send down the articles pagination data. So let's send that down separately and to do this we just use articles and to array.
06:47
If you need any tips on this if we head over to the length aware paginator and just take a look at the methods here we've got to array which gives us all of the data about the current page, the pages that we have and we can use this to control our pagination.
07:03
Okay so now that we've done that let's hop back over to articles. We can get rid of data now because we're not directly using that paginator. We still have 10 items. So the goal here is to first of all create a button in here
07:14
that we can click to append the next set of articles on and we know that because we are using merge here that's giving us back an array. These will be pushed as we looked at a little bit earlier in the course.
07:27
So let's go over to articles and we will create out a button just down here to load more. We'll just keep this really simple for now and in fact what I'm actually going to do as well is go ahead and just include the article id in here just so we can see that we're loading these in properly.
07:48
Okay great so the next thing we need to do is over in our articles hook this up to a method. So let's go ahead and call this load more. So when we click on this we'll load more and let's go ahead and create that method just at the top here.
08:03
So load more. We don't even have to create a method for this. We could do it all in line if we wanted to. Okay so to do this we'll go ahead and use our router.
08:10
So let's make sure we pull that in from Inertia B3 and we'll go ahead and reload here passing in the data that we need to pass in which is the new page. So what we have in here as well is the articles pagination data
08:27
which will be an array or an object because it's cast to an object and then we can basically pass along the new page. So the new page is going to be from our props which we can go ahead and name here and we're going to take the articles pagination current page
08:47
and we can add one to that and then down here underneath our data we can only load in articles, articles pagination. In fact let's rename this just so it's a little bit more consistent. So we'll say underscore pagination
09:06
and we should be good. Okay so we'll get the initial data down but when we click load more this will increment the current page. That will be sent along with the request in the query string or the request this
09:16
and we should get page two. It will reload the articles which remember are merged and it will give us back the new page in the articles pagination. Let's take a look so let's scroll down let's click on load more
09:28
and there we go you can see sure enough it's now loading more in. So just that on its own is a lot simpler now that we have Inertia v2 with the merging option. We haven't had to merge these manually at all
09:42
we just basically send another request down and this data gets merged in. Now we can create an infinite scroll using the when visible component and we're not going to need this load more method. I'll leave this here just in case you do want to use it
09:56
but let's go ahead and switch out this load more button for when visible. Let's go ahead and pull in when visible like we've already seen. We know that in here we want to take in the params that we want to send down with this request.
10:08
So there's a couple of ways that we could do this. What we're now saying is basically these params are going to be the things that we would normally pass to our route to replace method. So the params that we're sending down is going to be the data
10:21
that we want to send down with this request. We know that that is the new page so we can just do exactly the same thing. So we can say articles pagination current page plus one and then we can also pass that only data
10:36
so we know that we are fetching just articles and just reloading articles and the fresh articles pagination data as well. Now into here we can add anything. So we could even add a load more button if this functionality fails
10:51
but I'm just going to go ahead and add in loading for now or we could just add in an empty wrapper in there. Okay let's try this out. So I'm going to go back to page one here
10:59
and let's scroll down and see what happens and you can see sure enough that data gets loaded in. We've got loading in here which hasn't actually worked at the moment and that is because we need to provide the always option to this
11:13
because we want this to consistently observe not just once. It's always going to stop at the second page because the once functionality of this will just kick in and we'll only see this once.
11:26
So we're just going to say always in here and that's going to consistently now if we just scroll down, trigger then it's going to trigger again and just keep triggering all the way down.
11:35
So you can see now that I can just effortlessly scroll down the page and we get nice infinite scrolling. Let's take this a step further. We'll go over to our article seeder and let's go ahead and reseed this.
11:47
So just to clear everything out let's use article query and delete. So we just destroy everything beforehand. I'm going to go ahead and bump this down to just 100 articles just so it's a little bit more manageable
12:00
and then let's go ahead and rerun our seeder here which will clear that out for us. Okay great so let's go over and just give this a refresh and take away the page here
12:10
and yeah so sure enough this still works but we only have 100 articles. So eventually we reach the bottom. Now we've still got this loading indicator here which wouldn't ordinarily be shown
12:20
but what we could do is control what we see here. So for example we could do something like you have reached the end and you could show that either just always
12:31
or you could add a condition onto here. So for example we could say vif articles pagination current page is equal to the articles pagination
12:43
and let's just check our length aware paginator again just to see what data we've got in here. We've got last page. So we could check if that equals the last page
12:54
in which case we'll show you have reached the end. So now let's just try that again. Again getting rid of this page in here. Scroll all the way down to the end
13:02
and we don't see that so it's probably a good idea to say greater than or equal to because it might bump up the page number depending on where we are. So if we just scroll down now all the way to the end
13:14
you have reached the end. So there's a ton of stuff you could do with this but the whole point of combining these two features at least until there is a specific infinite scroll component release for v2
13:26
is we don't need to write much code up here at all. In fact with the solution that we've created we could just completely get rid of that load more. So there we go.
13:34
We haven't had to write any of our own javascript code to merge in the data that we get back from the client. This makes it a lot easier. But you have the option to just do load more if you want
13:45
using prop merging or you can use the when visible component to go ahead and use the Intersection Observer API to infinite scroll.
9 episodes1 hr 27 mins

Overview

With the release of Inertia v2, let’s cover everything new — now and into the future.

Each episode of this course will cover a new feature or significant change, so you’re ready to adapt and introduce new functionality into your Inertia-powered applications.

Alex Garrett-Smith
Alex Garrett-Smith
Hey, I'm the founder of Codecourse!

Episode discussion

No comments, yet. Be the first!