This episode is for members only

Sign up to access "Build a Livewire CSV Importer" right now.

Get started
Already a member? Sign in to continue
Playing
04. Using and toggling the importer

Transcript

00:00
A couple of parts ago, we created out the CSV importer component, which at the moment is completely empty.
00:05
We do know though that we've got all of the markup that we need for the actual component itself. Now, what we're going to do in this episode is create out a list of our customers so we can actually see them. And on that page that we create, we're going to add the importer and tell the importer which model this is for. This is really, really important because we need to specify this at the component level.
00:26
So everything we do inside of the component relates to that model within our application. And this makes it more flexible because then if we had another page with some other data, we could just reuse the same CSV importer. That's the goal of building this out.
00:41
Okay, so before we look at the actual CSV importer and toggling it and passing the model through, we're just going to really quickly create out a controller which deals with the data that we need. So we'll make this really, really basic. We're going to create a controller out here called CustomerIndexController.
00:57
And if we head over to our roots, let's register this out. So kind of like we've done with the dashboard, but we're using a controller here. So we're going to go ahead and say root get and customers. And let's reference that CustomerIndexController, the fully qualified namespace to that.
01:14
And then let's go ahead and open this CustomerIndexController up. And we'll just create out an invoke magic method in here just to keep things really, really simple so we don't have any methods hanging around. And we're going to go ahead and return a view in here.
01:27
That's just going to be customers.index. So if we head over to our resources under views, let's create a folder in here called customers. And let's create a file in here called index.blade.php. And what we can do is pretty much copy the dashboard structure for this.
01:43
So we just paste this in and just say customers. And at the top here, let's say customers. We head back over to our CustomerIndexController. We can then pass the data down to this and it should look good.
01:56
So if we head over here to our customers page, we see the customers page. Great. And that's where, of course, the importer is going to sit that we can toggle. Of course, this whole controller could actually be a LiveWire component if you wanted to do that at the root level. But we're not really interested in anything else at the moment.
02:14
We just kind of want to focus the LiveWire stuff on our actual app. So let's go to pass this data down. So we can just grab the customers. We'll use the latest scope here. And let's paginate this by 100. Really important because when we get to importing, say, 500,000, 1 million records,
02:36
we obviously don't want to show all of them on the page or it's probably going to crash. Okay. So now that we've done that, we've got the data. We have got the template. We can update the template just to really easily iterate through these. And we'll keep this super simple. I'm just going to nest some divs in here with a space Y of 1.
02:56
And let's go ahead and do a for each here. Customers as customer. And that in that for each out. And then in here, we'll just create another div just playing around here. And we'll output the customer ID. Pretty important because we need to keep a track of IDs. And let's add in the customer's first name. And we'll also add in the customer's last name as well.
03:26
And why don't we just have the company in here as well, just for good measure. So company. Okay. If we head over, there we go. We have got all of them records. Obviously, we're paginating by 100. We only have 100, but we kind of get the idea. So now what we can do is actually pull the Livewire component back into here.
03:44
Now, it doesn't matter where this goes on the page because it's fixed position on the right hand side. So I'm just going to put this down here outside of the last div or we could even tuck it inside of this div here. So let's again say Livewire CSV importer. And let's go and just give that a refresh or just wait for Vite to build that. So there we go. We have our import component. Now, we need to toggle this really importantly.
04:10
So we're going to need some sort of button here that we can use to toggle this. Let's go ahead and create that really quickly. So I'm actually going to go ahead and comment the CSV importer out so we don't see anything. And we're going to go over to the header of this page here and just pass this H2.
04:25
We're going to create a button out here, which will have the import text in. So this is where we're going to use Livewire to emit an event to this CSV component so we can toggle it. Now, we're assuming here that you're only ever going to have one import component on the same page. You might need to tweak this if you have multiple import components on one page, but doesn't really matter too much for now.
04:49
So let's just have a look at that. It's probably not going to look great at the moment, but we could probably tweak this. So I guess if we wrap this in a div here and we add some flex styling to this. So let's say flex item center and we'll just say justify between. That should go ahead and pop that over there. So the goal here now is to click on this and see that import component appear.
05:15
Now, you could do this with Alpine. I'm going to do this with Livewire. So we are sending additional network requests, but as per the Livewire performance course that we have, the advice there is if you're toggling something, it's probably better to use something like Alpine. We will be using Alpine later, but just not for this.
05:33
So if we head over to the CSV importer on here, we want some sort of property to show that the CSV importer is open. So just up here, we're going to create our public Boolean and we're just going to call this open. Now, by default, it's not going to be open, but we can create our toggle method in here, which changes this around. And then we can call that directly from JavaScript. So let's go ahead and create out this toggle method.
05:58
And all that's going to do is set the open property to the opposite of what open already is. So if it's false, it will go true. If it's true, it will go false. So how do we trigger this? And really importantly, how do we actually hide the component in the first place? Well, what we can do is head over to the CSV importer here and we can actually start to add some Alpine in.
06:19
Now, this isn't Alpine to toggle it. This is just Alpine to show it if the live wire data matches something very specifically. Now, Alpine.js is already pulled in when we have a fresh Laravel installed with Laravel Breeze. So we can just start by adding in our X data object here.
06:36
And basically, we just want some sort of open property to match what's currently within this live wire component. Now, to do that, we can use the entangle functionality, if I can spell it, and we can go ahead and say open. So this value will match what we have over in the CSV importer here, which is really handy because then now we have access to that directly in JavaScript.
07:00
We can go ahead and show this entire component if this is true. So to do that, we're going to go ahead and say X show open. Now, what we should see if we head over and give this a refresh or just wait for Vite to build, it shouldn't be open. But if we go and manually switch this to true and we come back over, we should see that this is open.
07:22
Now, at the moment, it doesn't look like it is. So let's just figure out what is happening here. I have a feeling that we didn't read. Yeah, so it's still commented out.
07:32
Of course, it's not going to show. So there we go. It's shown now. And if we head back over to CSV importer and set this to false, you can see it goes. Perfect.
07:40
So now we just need to toggle this so we can show it and make sure that we pass that model down to that component so we know what kind of data we're dealing with. So to do this, we are going to head back over to our index. And this button here is going to be responsible for specifically emitting an event to that CSV component.
08:00
So the CSV component itself and calling that toggle method. So in here, we're going to go ahead and just set X data. So we initialize another Alpine component. And then we're going to use a click event handler to access live wire on the window object.
08:18
And we're going to emit specifically to, we don't necessarily want to emit this globally. There's not really much point. We want to emit this to our CSV importer component. And we're going to emit a toggle event.
08:30
That is pretty much it. So now when we click on this button, this is going to fire event off. Our CSV component here can listen to that and it can toggle it. Now, this isn't the same as calling the method.
08:41
Notice at the moment, if we click on this, nothing happens. The reason being is that we're just emitting a toggle event. We're not calling the toggle method. To handle that, we need to go into the CSV importer and set up a listener.
08:54
So let's do this just at the top here. And we're going to say protected listeners. This is an array. You can define this out as a method if you want to.
09:04
And we want to listen to the toggle event and call the toggle method when we receive a toggle event. Now because these two methods are the same, we don't need to provide the value or we can just include a value more like and just have toggle in there. So if we head over now and hit import, there we go.
09:21
Our CSV importer appears. Now we need to figure out how to close it because at the moment the only way to do that would be to refresh the page. So that's going to be inside of the CSV importer component itself.
09:32
And let's just go down to close panel here. This is the button that is going to close that. So this one's easy because we're already within the LiveWire component. So we don't need to emit any kind of event.
09:43
We could do if you wanted to, but the easiest way to do this is just to set up a wire event handler, a wire click event handler for LiveWire and just immediately invoke that toggle method rather than going through the event listener.
09:57
So now if we just go over to import and click this off, there we go. We're effectively toggling this open close. That's how simple it is. So lastly and really importantly we need to pass through the type of model
10:09
that we're working with inside of this particular instance of this CSV importer. So if we come over to index.blade.php and we head down to where we define this, effectively what we want to do is pass in the model that we're working with. Now this is going to be the fully qualified namespace to the model
10:26
so we can make use of it properly. We're not just going to write customer in there. We could do that and then work it out later, but we're just going to for now even though it's a slightly messy,
10:37
give the full namespace to our customer model and they're binding this in because we're using a class with a scope resolution operator to grab the fully qualified namespace. So now that we've done that over in the CSV importer class itself,
10:52
we can go ahead and define out a string in here because that is a string which is the model. So now we can access this when we're creating a job so we know which data to actually import and all that kind of stuff.
11:05
Grab the columns, whatever we need to do. So with this, let's just test this out by going over to our CSV importer component. We'll just do this somewhere maybe in the header. It doesn't really matter where we do it
11:18
and we're just going to output model just to make sure that the fully qualified namespace is being passed through properly. So when we hit import, there it is. So we now know which type of data we want to import
11:30
using this specific instance of this importer. So we're going to go ahead and get rid of that because we don't need to show it, but that is our importer now toggled. One thing actually before we go,
11:40
notice that we have this kind of flicker when we refresh the page. That's just because Alpine hasn't loaded in yet. So if we head up to here, XShow hasn't got the opportunity to hide this before Alpine has loaded. Now we can get around that using XCloak.
11:56
We literally just need to put XCloak into this particular div and what's going to happen is this is going to add an attribute to this, which when Alpine loads, it will automatically get rid of it and that gives us the opportunity to assign some styles to this cloaked element
12:13
before Alpine initializes. Now to do this, we need to come over to resources and CSS and we need to define some stuff in here for styling to hide any cloaked element before this happens. So this will add the XCloak attribute.
12:29
So we can just style up the XCloak attribute to have a display of none and we can say important on this because we need to definitely hide this and we need this to override anything in the cascade.
12:42
So now that we've got this style in here, what's going to happen is when we refresh the page, we don't see that flicker because this XCloak attribute will exist on that element
12:51
until Alpine initializes and now we can just toggle it like normal. Okay, great. So we've got our importer with the model passed in. We can toggle it. Now we can start to look at accepting a file in and validating that file.
25 episodes2 hrs 20 mins

Overview

Let's build a powerful CSV importer with Livewire, completely from scratch. This can handle millions of rows, be reused for multiple models, and by using job batches, doesn't require the browser to be open.

This course is for you if:

  • You need a robust importer component for your models that you have full control over
  • You want to brush up on some advanced Livewire concepts
  • You want to learn about job batching and queues in Laravel
Alex Garrett-Smith
Alex Garrett-Smith
Hey, I'm the founder of Codecourse!

Comments

No comments, yet. Be the first to leave a comment.