Introduce JSON resources0:00
As it stands now we're sending a little bit too much data to the front end and also that data doesn't have quite the shape that we want. So let's fix this with JSON resources. To show you what I mean. Let me bring back the pre tag where we had the JSON string outputs of the puppies. And so for each puppy we had fields like the created_at, updated_at, and all the user information, including the email address, which I don't think
updated A and all the User information, including the email address, which I don't think that we want to include here. So we are going to reel this back in by setting up a JSON resource for the puppy. So a Puppy resource. And we are going to be selective about what we pass to the front end. Let's run the command to generate a JSON resource, php artisan make:resource.
Let's run the command to generate AJAX resource, php artisan make:resource. And here I want the resource to be PuppyResource. All right, so here it is. Okay? And so here, instead of returning the entire data, we are going to return only specific fields. So we definitely want the id that's always useful to pass in as a key in React. And then we'll want to pass the name and trait fields for sure as well as the image URL.
And then we'll want to pass the name and trait fields for sure as well as the imageUrl. But here we're going to change the formats to camel casing name and then trait. And then we are going to have imageUrl that points to this image URL. And then we'll also want to pass the User that is attached to the Puppy. So let's pass the whole User for now, but we're also going to create
So let's pass the whole User for now, but we also going to create a JsonResource for the users. So user, this user, but as you've seen Copilot suggest we only want to show the user if it has been loaded because remember this is a relationship that we do an extra query for. So in our homepage here, when we load the user, we want to actually add this to the JSON resource.
Use PuppyResource in Inertia2:03
So in our homepage here, when we load the User, we want to actually add this to the JSON resource. And so we can wrap this in a whenLoaded and here pass the User like this. Okay, so I think this is a good starting point. So let's try and now use this PuppyResource and see what we get in the front end. So in the welcome route, the Inertia response here, we are going to wrap the puppies here in PuppyResource::collection like so.
we are going to wrap the Puppy here in Resource collection like so. So instead of passing the straight Eloquent models here, we are going to pass a series of JSON resources that we've just created. And whoops, we got a blank page. And if we inspect the console, you'll see that puppies, that map is not a function. So this happens because by default a JSON resource is going to wrap all the data in a data property.
Remove data wrapping2:49
So this happens because by default a JSON resource is going to wrap all the data in a data property. Uh, so that's useful for when you do APIs and you want to be able to check if there is some data in the response when you do a fetch from the client side. But when using Inertia, we don't really need to worry about this. So one thing we can do is resolve the JSON resource collection results. So we are going to directly drill inside this data property.
resource collection results. So we are going to directly drill inside this data properly. But before I do this, let me just comment out the undo list here because this is what creates the error with the puppies map here. Just to show you that there is this wrapping data property and you can see it here. So the array of puppies is still here, but it's inside a data attribute. And so you can see the data is already cleaner.
but it's inside a data attribute. And so you can see the data is already cleaner. We now have the ID, name, Trait, and image, URL. These are the only fields that we've defined in the JSON resource and we are still passing the entire User here. So let me get rid of the data wrapping. And so like I mentioned where we use the PuppyResource collection, we can resolve that collection. And this is going to get rid of the data wrapping,
collection, we can resolve that collection. And this is going to get rid of the data wrapping, but if you wanted to do this for all adjacent resources, which we kind of do, we can do this at the app ServiceProvider level. So in the Laravel documentation for API resources, if I go to data wrapping, you can see that we can globally disable this with JSONResource without wrapping. And so that's the app ServiceProvider. So let's go in the app ServiceProvider
And so that's the AppServiceProvider. So let's go in the AppServiceProvider and find the boot method here and we can paste that here. And of course we need to import the JsonResource like so and so now I can get rid of the resolve call here and our puppies will still be unwrapped, no data wrapping properly to be found. Alright, very nice. So moving on, just before we create the UserResource, I just want
Create UserResource4:42
So moving on, just before we create the User resource, I just want to test the whenLoaded functionality on the User here on the Puppy resource. So what I'm hoping here is if we remove the loadUser, the User is not going to be passed in the resource and yep, that is the case. Excellent. It's working. Alright, let's bring the User back and let's now create the User resource. I should be able to press the app arrow
and let's now create the UserResource. I should be able to press the app arrow to trigger the previous command. Yep. So this time we want a UserResource and let's go customize it. So again, we don't want to pass all of it. So copilot really insists on helping. So let's allow that, but I don't really need this and I don't wanna show the email. So let's keep these two fields for now.
and I don't wanna show the email. So let's keep these two fields for now. And so right now we not using that User resource yet. So there's all these fields and I think really these two are just what we want at least for now. Okay, so let's keep it simple for now. We can come back to this later. And now I can go back to my Puppy resource and instead of passing the User here, we are going
And now I can go back to my PuppyResource and instead of passing the User here, we are going to pass a collection entry for the UserResource. So UserResource and because it's just one we can go make and that should do the trick nicely. So if the User is loaded, we make a UserResource with that User and as a result we have a User with the ID and name properties just like we've defined. So every puppy is attached to Simon.
and name properties just like we've defined. So every Puppy is attached to Simon. For now I've got lots of Puppys, but this is going to change in the future. Let's verify one more time that this functionality works when the User is not loaded and it is beautiful. Alright, so let's bring back a User and I will hide the ified list, but show the actual list that we had.
Update frontend types6:23
and I will hide the ified list, but show the actual list that we had. As you can see, this is going to be broken just now because now this warning is actually coming true. So the images will not show because now the JSON resource is returning a camelCase image URL. So let's fix that and I can use Autocomplete for this. So I'm going to ask what's available and use imageUrl. And so now the images are back.
So I'm going to ask what's available and use image URL. And so now the images are back. And speaking of TypeScript, I want to quickly go update the puppy type because now we've added the user to the puppy resource, the JSON resource. So we need to reflect that for our front end types. So if I go to Types index, we do have these four properties. Uh, this one is not available here and this is going to be the topic of our next lesson.
Uh, this one is not available here and this is going to be the topic of our next lesson. But for now, let's also add a User, which is going to be an object with an id, which is going to be the type of user, the ID, property and the name. And so I think we could be fancy here and use instead the pick that is going to let us pick specific properties of a type and exactly like this. We're going to pick the User and then have the ID.
of a type and exactly like this. We're going to pick the User and then have the id and name properties. So that is now reflecting precisely what we pass in the JSON resource. And so it makes it easier if we want it, for example, to say that the Puppy is owned by. And if I go puppy that I will now be able to drill down to the User and see that there is an id and a name and that my friend is excellent.
to the user and see that there is an ID and a name and that my friend is excellent. Let's maybe wrap this in a div because of the flex parents. And check this out. All the puppies owned by Simon. Alright, we are in a much better place now. We passing just the data that we need and want and in the shape that we want to the front end. So it's much easier to maintain and also more secure and privacy respecting.
Next: likedBy relationship8:09
So it's much easier to maintain and also more secure and privacy respecting. And so the next thing we want to do, because we're getting really close to be able to replace the puppies list with the actual Laravel backend data. But before we do this, we just need to set up the likedBy relationship between the Puppy and the User. So let's do that in the next lesson.
So let's do that in the next lesson.
