تماشای این درس نیاز به اشتراک حرفه‌ای دارد.

Collections vs Arrays0:00

Okay, we have our to-do app working, we click on add to-do, and then some to-do gets added to our array of to-do's. So let's take a look at that array. Here's this array of to-do's. Now consider this. This works all fine with a plain array, but let's just say that instead of an array, again, you might have been getting this data from a database or something, and you might want to-do's to be an Eloquent collection. And if you're not familiar with those, they basically just wrap up plain arrays and give you lots of convenient methods around arrays.

And if you're not familiar with those, they basically just wrap up plain arrays and give you lots of convenient methods around arrays. So let's just say, instead of just using this plain array syntax to add the draft inside of addToDo, let's use an Eloquent method, sorry, a collection method called push, where we push the data on to the collection. So this makes sense. And if we forget about Livewire for a second, if we were just using this in php as a normal class, we could totally set a property to a collection, and then later on we could access that collection and push on to it. That would totally work.

Why Push Fails0:59

that collection and push on to it. That would totally work. But in Livewire, this isn't going to work, and let's talk about why. So let's try it first. We'll open up the network tab so we can see our error. We hit add to-do. Okay, here's the error. It says, call to a member function push on array. So what's happening is this is no longer a collection. It's now an array.

So what's happening is this is no longer a collection. It's now an array. And if you think about it, that kind of makes sense, because in the first pass of the component when we render the page, todos is set to a collection, it renders the HTML, and that's why we don't get an error on first load. But let's look at the snapshot that's stored in the HTML. The snapshot from, remember, our toSnapshot method? Well here it is. Data todos is just a plain array. And that's because JavaScript doesn't understand PHP, of course.

Data todos is just a plain array. And that's because JavaScript doesn't understand PHP, of course. There's no collection inside of JavaScript for it to preserve. Any data in PHP gets converted into JavaScript-safe data, and then when it comes back to PHP, you've lost that information. It just comes back as a plain array. There's no way for PHP to know that it was once a collection. So when we do the fromSnapshot method and build up this component again after we click add to-do, todos turns back into a plain array. We're trying to call push on a plain array, and then we get that error.

Adding Snapshot Metadata2:11

add to-do, todos turns back into a plain array. We're trying to call push on a plain array, and then we get that error. So it makes sense that this is erroring in the way that it does. So if we want to support collections, and Livewire does, Livewire itself supports collections, it supports Eloquent methods, date, time objects, all sorts of these PHP classes and objects that don't exist in JavaScript, it supports them by adding metadata to the snapshot. So a snapshot might look just like this, but there might also be an additional key called meta. In actual Livewire, it's called data meta, which is such a dumb name, whatever, that's on me.

In actual Livewire, it's called data meta, which is such a dumb name, whatever, that's on me. So we're just going to call it meta. And meta might have some information about todos, saying, hey, todos is actually a collection. So let me kind of write out the schema that I'm talking about. So right now, a snapshot looks like this. We have a class. And in this case, it's, you know, app/Http/Livewire/Todos. And then we have data, which is going to be todos, and then, you know, some array. Now we want to add a third one called meta, that describes data keys like this, so that

And then we have data, which is going to be todos, and then, you know, some array. Now we want to add a third one called meta, that describes data keys like this, so that when we make the snapshot, we can add this metadata. And then when we convert the snapshot back into the component, we can look for metadata first, and then hydrate up the proper data, and then set the properties. So let's do that. Fortunately, because like I was talking about, the only two places we care about are when we make the snapshot and when we use the snapshot. So if we go into our Livewire God class here, we have this toSnapshot method, and fromSnapshot.

So if we go into our Livewire God class here, we have this snapshot method, and from snapshot. And that's it. Those are the only two methods that we actually need to modify. So let's do it. We're just going to modify these methods. We'll start by just modifying the methods, and then we'll implement them and make them work. Okay, so here's snapshot, we have class data. Now let's add meta.

Dehydrating Properties4:00

Okay, so here's snapshot, we have class data. Now let's add meta. Okay, now what goes here? Well, let's create a new variable called meta. And this is what we're going to do because properties, we're also going to need to change because we don't want that to actually be a collection. So we're going to think of this as dehydrating a components data into data and metadata from normal properties. So check this out. Let's create a new method, we're going to call it dehydrateProperties.

So check this out. Let's create a new method, we're going to call it dehydrateProperties. And we'll pass this the properties and our return value. Let's make it data and meta. We'll make it a tuple because these things travel in pairs, the data and then the metadata about the data. Have I said data enough? All right, so let's implement this dehydrateProperties function, create a function called dehydrateProperties. And this accepts a properties parameter.

dehydrate properties. And this accepts a properties parameter. Okay. All right, now inside of here, let's build up two variables meta and data. And we're going to set these to an array initially. And then we can loop through the properties as key value. And let's forget about this, you know, any extra logic, we're just going to for now take we'll build up this empty data array with exactly what's inside properties for now. So data at the specific key equals value. And what we're really doing here is just copying properties into a new array.

So data at the specific key equals value. And what we're really doing here is just copying properties into a new array. But we'll add the extra metadata stuff in a second. And then we can return data and meta. Okay, now here's where the actual foo comes in, we're going to splice in a little conditional we'll say if value is an instance of an Eloquent not why don't you say Eloquent, just a layer of Collection, then let's set value equal to value->toArray(). So this is a method that exists on collections where we convert a collection into a plain array. So we need to do that.

array. So we need to do that. And we also need to add some metadata. So we'll say in this meta array, add the key, which in our case is toDues. So add this toDues key and set that equal to a key, just some kind of identifier that we can look for on the way back. So when we create the alternate method called hydrateProperties, we'll look through the metadata, we'll see that okay, the toDues property is supposed to be a collection. And then we'll turn it back into a collection after we just converted it from a collection into an array.

And then we'll turn it back into a Collection after we just converted it from a Collection into an array. So this is all the data we need. Let's use this method in our code. Let's just kind of render this and see how it didn't work. All right, we Okay, well, it actually totally did work. Let's take a look at why, why did it work? Okay, I guess I was thinking that we needed to do something else somewhere else. But that's so silly. Because like I said, toSnapshot, and fromSnapshot are the only places we need to modify.

Hydrating Back to Collections7:05

with the metadata on the reverse side. Okay, so we have this to snapshot, we take these properties, and we turn them into data and metadata and put those in the snapshot. Now let's do the opposite inside from snapshot. So when the snapshot comes to the server, we will then create a new piece of data called meta. Okay. And before we set properties here, let's do this. Let's say properties, whoops, not that properties equals, and we'll create a new function called hydrate, hydrate properties, okay, where we pass in the data and the metadata

Let's say properties, whoops, not that properties equals, and we'll create a new function called hydrate, hydrate properties, okay, where we pass in the data and the metadata about the data. All right. And then we pass in those hydrated properties to set on the component, and then everything is good in life. So let's create this function, function hydrate properties, this accepts the data and the metadata. Okay, and then we'll kind of use a similar pattern as before, we'll create an empty array that we're going to build up and eventually return.

Okay, and then we'll kind of use a similar pattern as before, we'll create an empty array that we're going to build up and eventually return. But in between, we will loop through the $data, and we'll look for $metadata that exists to change it. So before we do that, again, let's just create a very transparent function that just copies the data to this $properties array. So let's do that. Let's say $properties[$key] = $value, okay. And that's not how you write an equals in php. Cool.

And that's not how you write an equals in php. Cool. And then let's do our metadata logic. So we could say if isSet, if there is a key existing, so for this specific property, in our case, it is if there is a metadata key, and if that key is equal to collection, if the key's value, okay, then turn that piece of data back into a collection. So it'll take value, we'll say value equals, and we'll just wrap it up in a collection. Okay, so this should work. And just to reiterate this logic earlier in the logic, we took properties, we said, hey, if one of the properties is a collection, add a key to the meta that says it's a collection.

And just to reiterate this logic earlier in the logic, we took properties, we said, hey, if one of the properties is a collection, add a key to the meta that says it's a collection. Now on the way back, go through all the properties or the data. And if there's a key in metadata, then and if it's also a collection, then turn it back into a collection before you set it as a property. And then remember that here's properties, it'll get set on the component. So if you followed all that, and we refresh, we see our meta. Now if we hit addToDo, bam, it works, we know that it got turned into a collection, we can verify this, let's go into our component. And inside addToDo, let's dd this $todos and verify that it is indeed a collection.

Verifying the Fix9:34

we can verify this, let's go into our component. And inside addTodo, let's dd this arrow to todos and verify that it is indeed a collection. And we actually need to open up the network tab to get that dd result. So let's hit addTodo, we get an error because we did and here's the result of our dd. It's Illuminate\Support\Collection. And there it is items. So this is a big piece of how Livewire creates a magical experience. This is what when people refer to the magic of Livewire, it's all this kind of work that goes on under the hood to create an experience that you're just working in plain old php. And it all magically just talks to a browser and works.

Collection SupportStore Meta Data

دوست دارید گاهی خبرهای Laracasts را ایمیل کنیم؟