Filter Data on a Vue Frontend with Laravel Query Builder from Spatie — Transcript

Transcript of the free Vue.js lesson Filter Data on a Vue Frontend with Laravel Query Builder from Spatiewatch the video lesson.

Right now we have a search input on our page that doesn't do anything. Let's send a request to our backend whenever the value of this input changes. That way our backend can respond with the filtered data. Now out of the box, Laravel doesn't have a way to handle let's say a filter parameter like the page parameter we've already used.

But pair it with a library like Laravel Query Builder and actually things become quite simple. With Laravel Query Builder, you can support query string parameters like this extremely quickly. So let's take a look at how this example works. You call a QueryBuilderFor method on the model that you want to query your database for.

And then you just set some filters that you're going to allow your front end to filter by. And this will get passed on to the database. And ultimately, you'll get users back that only contain John within their name and Gmail within their email address. So simply put, with a single line in our backend, we can support filter query parameters from our frontend.

This is exactly what we need. In fact, if you take a look at our backend code, you'll find I've already set this up. Inside of our index function, inside of the links controller. We're using query builder four on the link class and I'm allowing filters for the full link column in our database and the short link column in our database.

Let's head back over to our front end and let's see if we can start sending requests to filter by the full link. So we've actually already completed the exact process needed for this feature when we coded out the page feature. That is, we need to set the page to some initial value, we need to watch that for changes, and then whenever it changes, make the request again, changing the query string that we pass the request. This is the exact same process we want for our filter.

So let's refactor just a little bit so that we can handle both at one time. Here near the top of my script setup section, Let's create a new reactive ref called queries. I will set this to an object and this will hold all the queries that we want both to show in our application URL but also in the URL that we're going to send to our backend. So this of course includes page and we'll set it at a default of one like we were doing before but this is also going to include our filter.

Now you'll notice though back in the Laravel query docs We've got a query string parameter that looks just a little bit weird, right? It's not just filter, but it's filter with the square brackets and then the particular field that you want to filter on. Now, PHP can actually handle and parse this type of query variable very easily. Unfortunately, there's no great way to get an object, a filter object with properties that are the field names, easily to a query string.

such as this. So what we're going to do is we're just going to use this whole bit here as our property name. There are other libraries out there for JavaScript that can handle objects and stringify them down to this format, but this approach is going to work just fine for our use case. So back here we're going to change filter to filter and then square brackets full link.

Make sure you do surround this with quotes since we're using characters in here that will mess things up in JavaScript if we didn't have the quotes and Of course, we'll just default our filter to an empty string now in our page reactive wrap down here We are defaulting its value to the page from the application query string So we can actually take care of both query strings at once by cutting this and then spreading it into our queries array. So if page exists in query, it will take over this default page here and likewise for the filter. Excellent. So now let's delete page altogether and let's make sure our entire application is still working with page now being defined within queries.

So that's going to involve just a couple changes. Here on watch, I need to change page here now to queries. Also add the deep option since we're working with an object and we need to watch the deep properties for changes. All right.

This hard-coded object page with the value of page value can go away and we'll simply set it to the value of queries. That way we can handle all the queries at one time. Finally, where we're manually assembling the query string here in the actual request to the backend, Let's make this account for all the queries in that QueriesReactiveRef. The way I want to do that is with the URLSearchParameters class built into the browser.

This takes an object which we can then convert to the string version of our query string. Excellent. And the method to change it into a string is just called toString. Now, I do get a red squiggly line here.

telling me that the argument of type page number and filter string is not assignable to type all this jazz. Basically what it boils down to is it doesn't like the fact that page is a number. But I just happen to know that URL search params is going to convert that number. It's going to coerce that number to a string just fine.

So I'll just add in a little comment here, letting TypeScript know we know everything's going to be okay. Great. Now let's store the result of this to a variable called qs. And then we'll use qs down here to finish off our string.

That should handle everything in our script setup section, I believe. The last thing we need to do in order for page to continue working is update the event that we're listening to on the pagination component. This is no longer page directly. page.

Perfect. So over in my browser, let me give it a refresh. Whoops, we have an error here. And that's because my IDE incorrectly imported URL search params here from the Node URL module.

That's not what I want. I want the URL search params that's available globally in the browser. Awesome. So one more error it looks like to deal with.

We'll inspect, check out the console. And it looks like the way we inserted our full link here. isn't quite right we put quotes around it right here that is not needed excellent so now our page is working again i can click between the different pages of data and you'll notice we also have this filter variable in our query string but typing inside of the search here still doesn't do anything okay daniel so what have we actually accomplished well now we've made it where we can add one simple step to get this working. That is down here on the search input component.

Let's add a V model and bind it to the filter inside of that query's reactive ref. That way, whenever we type in the input, everything is going to kick off just like with the page query. All right. Moment of truth.

Awesome. Sure enough, this works like a charm. In fact, it works a little too well because we're remaking the request on every single keystroke, which honestly is just an unnecessary burden on our backend. In the next lesson, let's debounce this so we're not making the request so often.

Right now we have a search input on our page that doesn't do anything. Let's send a request to our backend whenever the value of this input changes. That way our backend can respond with the filtered data. Now out of the box, Laravel doesn't have a way to handle let's say a filter parameter like the page parameter we've already used.

But pair it with a library like Laravel Query Builder and actually things become quite simple. With Laravel Query Builder, you can support query string parameters like this extremely quickly. So let's take a look at how this example works. You call a QueryBuilderFor method on the model that you want to query your database for.

And then you just set some filters that you're going to allow your front end to filter by. And this will get passed on to the database. And ultimately, you'll get users back that only contain John within their name and Gmail within their email address. So simply put, with a single line in our backend, we can support filter query parameters from our frontend.

This is exactly what we need. In fact, if you take a look at our backend code, you'll find I've already set this up. Inside of our index function, inside of the links controller. We're using query builder four on the link class and I'm allowing filters for the full link column in our database and the short link column in our database.

Let's head back over to our front end and let's see if we can start sending requests to filter by the full link. So we've actually already completed the exact process needed for this feature when we coded out the page feature. That is, we need to set the page to some initial value, we need to watch that for changes, and then whenever it changes, make the request again, changing the query string that we pass the request. This is the exact same process we want for our filter.

So let's refactor just a little bit so that we can handle both at one time. Here near the top of my script setup section, Let's create a new reactive ref called queries. I will set this to an object and this will hold all the queries that we want both to show in our application URL but also in the URL that we're going to send to our backend. So this of course includes page and we'll set it at a default of one like we were doing before but this is also going to include our filter.

Now you'll notice though back in the Laravel query docs We've got a query string parameter that looks just a little bit weird, right? It's not just filter, but it's filter with the square brackets and then the particular field that you want to filter on. Now, PHP can actually handle and parse this type of query variable very easily. Unfortunately, there's no great way to get an object, a filter object with properties that are the field names, easily to a query string.

such as this. So what we're going to do is we're just going to use this whole bit here as our property name. There are other libraries out there for JavaScript that can handle objects and stringify them down to this format, but this approach is going to work just fine for our use case. So back here we're going to change filter to filter and then square brackets full link.

Make sure you do surround this with quotes since we're using characters in here that will mess things up in JavaScript if we didn't have the quotes and Of course, we'll just default our filter to an empty string now in our page reactive wrap down here We are defaulting its value to the page from the application query string So we can actually take care of both query strings at once by cutting this and then spreading it into our queries array. So if page exists in query, it will take over this default page here and likewise for the filter. Excellent. So now let's delete page altogether and let's make sure our entire application is still working with page now being defined within queries.

So that's going to involve just a couple changes. Here on watch, I need to change page here now to queries. Also add the deep option since we're working with an object and we need to watch the deep properties for changes. All right.

This hard-coded object page with the value of page value can go away and we'll simply set it to the value of queries. That way we can handle all the queries at one time. Finally, where we're manually assembling the query string here in the actual request to the backend, Let's make this account for all the queries in that QueriesReactiveRef. The way I want to do that is with the URLSearchParameters class built into the browser.

This takes an object which we can then convert to the string version of our query string. Excellent. And the method to change it into a string is just called toString. Now, I do get a red squiggly line here.

telling me that the argument of type page number and filter string is not assignable to type all this jazz. Basically what it boils down to is it doesn't like the fact that page is a number. But I just happen to know that URL search params is going to convert that number. It's going to coerce that number to a string just fine.

So I'll just add in a little comment here, letting TypeScript know we know everything's going to be okay. Great. Now let's store the result of this to a variable called qs. And then we'll use qs down here to finish off our string.

That should handle everything in our script setup section, I believe. The last thing we need to do in order for page to continue working is update the event that we're listening to on the pagination component. This is no longer page directly. page.

Perfect. So over in my browser, let me give it a refresh. Whoops, we have an error here. And that's because my IDE incorrectly imported URL search params here from the Node URL module.

That's not what I want. I want the URL search params that's available globally in the browser. Awesome. So one more error it looks like to deal with.

We'll inspect, check out the console. And it looks like the way we inserted our full link here. isn't quite right we put quotes around it right here that is not needed excellent so now our page is working again i can click between the different pages of data and you'll notice we also have this filter variable in our query string but typing inside of the search here still doesn't do anything okay daniel so what have we actually accomplished well now we've made it where we can add one simple step to get this working. That is down here on the search input component.

Let's add a V model and bind it to the filter inside of that query's reactive ref. That way, whenever we type in the input, everything is going to kick off just like with the page query. All right. Moment of truth.

Awesome. Sure enough, this works like a charm. In fact, it works a little too well because we're remaking the request on every single keystroke, which honestly is just an unnecessary burden on our backend. In the next lesson, let's debounce this so we're not making the request so often.