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

Flow API data0:00

Enough of playing with colorful boxes. This time we're going to take the API data, the puppies and try to flow them through our application. So we're going to break everything and then through the help of TypeScript, we are going to refactor our way into an app that works again. And I think that if you did not like TypeScript up to this point, this might be the moment where things click for you. We are going to set the puppy type in our application.

where things click for you. We are going to set the puppy type in our application to match the API data and then literally follow along the recommendation or the instructions of TypeScript of what is wrong in our app until we fix it. Let's get into it. So we are going to have a similar setup, but instead of the error boundary and the Suspense wrapping this placeholder demo API puppies,

Move Suspense to Main0:46

but instead of the error boundary and the Suspense wrapping this placeholder demo API puppies, I want to move this up one level. So I'll cut it and I want to wrap the actual Main component because everything inside of Main, so the Search, the ShortList, the PuppiesList, and even the NewPuppyForm sort of needs to have the puppies data before it makes any sense. Let me remove this. Two. We can get rid of the api puppies, which was a demo,

Let me remove this. Two. We can get rid of the API puppies, which was a demo, but we are still interested in this. Ah, I'll delete all of it and we will redo it. But I will get this puppyPromise outside of my main function here, I will get the puppyPromise like we've done before. And so inside the main component, I can suspend that main component by using the use function cons. API puppies = usePuppyPromise that is going

that main component by using the use function const apiPuppies equals usePuppyPromise that is going to suspend everything below until the promise is resolved. So my thought here is instead of having the puppies data as the default value for our state puppies, remember the puppies data is the static data from the local file. Instead of that, we want to set our puppies to apiPuppies and then it's going to render the rest.

API puppies and then it's going to render the rest of the application like before. But all of this should be suspended until this has resolved because we are wrapping it in a Suspense component. Okay, we have two problems here. The first one is our data is wrapped in the data key, which we didn't have before. And then the shape of each puppy is a little different.

Update Puppy types2:26

which we didn't have before. And then the shape of each puppy is a little different. So I wanna go in the types and make sure that we are matching what comes from the API. So I'm going to copy actually the whole object here and go in the types file. And for our puppy shape, you can see that the ID matches the name matches. But then we want to go back to this trait here. The imagePath is actually imageUrl.

But then we want to go back to this trait here. The imagePath is actually imageURL. And we have this likedBy array. And what dislikedBy array is, yes, it's an array of number and this represents a User. Let me delete that. If we were doing more things with users, we would also do a userType like this. And I'll just keep the ID here. And here we could go userID and an array of, alright, so this is going

And here we could go userId and an array of, alright, so this is going to guide us in our refactor process. But the other issue we have in app.tsx is our puppies data is supposed to be an array of puppies, but if I try to console.log it here, puppies is an object that has a data key. And then inside we have our puppies array. And we do not want that. We basically want just the array with 12 puppies.

Unwrap API response3:37

And we do not want that. We basically want just the array with 12 puppies. So why don't we modify our query and instead of returning data, the structure, the data from the data object here, and this time when I refresh the data should be just an array of 12 puppies. Alright? And the error message has changed, which is a good sign, but I said we were going to use TypeScript to help us through the refactoring.

Refactor with TypeScript errors3:57

which is a good sign, but I said we were going to use TypeScript to help us through the refactoring. So let's follow the lead. Now that we've changed our puppy type, we should have some errors. If I run the type checker with npm run check, we have five errors across three files: the new puppy form, the puppy list, and the short list. Let's start with the short list. And we can see some reds down the bottom here.

Let's start with the short list. And we can see some reds down the bottom here. And here it's telling us that the image path is incorrect. Remember we changed that to image URL. And if I go control space, I'll go with the autocomplete suggestion here. We should be good with the short list. What about the puppies list? Ooh yes. I see lots of errors here. So first one is we're trying to filter by vibe to lowercase.

I see lots of errors here. So first one is we're trying to filter by vibe to lowercase. So as we know, the API puppies do not have a vibe, but they have a trait instead. And look at this, we already have some of our app working again. Alright, so let's keep going. There's other errors on the page. This is not image path, but image URL. And this is not vibe but trait. No more errors.

This is not image path, but image URL. And this is not vibe but trait. No more errors. There was an error in the new puppy form as well. Where is it? Is it in this toggled code? Yep. Here we're trying to pass vibe when we create a new puppy, but we need to pass trait and image URL thank you TypeScript because of the type we've added here and huh, interesting. You can see that now new puppy is complaining that it's missing the likedBy array that we've added.

You can see that now new puppy is complaining that it's missing the likedBy array that we've added to a type this array of User IDs. So our app doesn't have that concept of users at this point. So we'll assume our current user has the idea of one. And so because it's a new puppy, it hasn't been liked by any other users. So we can go likedBy and have an array with one here. Alright? And believe it or not, this is the data

Alright? And believe it or not, this is the data that comes from the API from the Laravel API. And if you weren't sure, this is my debugging trying stuff out. Uh, so you can see that it works. This is funny. So I'm just going to reset my seed data with php artisan migrate:fresh --seed. And so when I refresh, I should only have nine puppies from the API.

Replace local likes with API6:09

And so when I refresh, I should only have nine puppies from the API. And hopefully now you believe me that this comes from the Laravel app. And speaking of Laravel API, our liked puppies coming from the API are not yet reflected right now we're still having our custom made liked status coming from local state. Remember in our main component we have disliked array defaulting to one and three.

Remember in our main component we have disliked array defaulting to one and three and then we can toggle that internally. But this completely bypasses the lateral API. And in the API we'll have an endpoint that lets us toggle the liked status for a given puppy. And so we're going to try to implement that instead. Alright, let's start with the puppies list. So I'm going to get rid of the liked and set liked local state that is going to break the app.

So I'm going to get rid of the liked and setLiked local state that is going to break the app. And instead of just passing the idea to the toggle, I will pass the whole puppy because inside that puppy data is the likedBy array that we need. So let's go inside the liked toggle. I will not receive the liked and setLiked and therefore not import the types from React. And I will comment out the setTimeout here.

therefore not import the types from React. And I will comment out the setTimeout here. Since none of this is working anymore, I need to update my type to not be an id, but an entire Puppy, which is the whole Puppy type. And so before we do the actual update functionality, let's do the display functionality. The logic here for now is, does the liked array that doesn't exist anymore includes the puppyId if yes, do this otherwise do that.

that doesn't exist anymore includes the puppyId if yes, do this otherwise do that. We wanna change this condition to check if the puppy that liked by property, like by array includes. And remember, we assume everyone is User number one. And so if the puppy is liked by User number one, it should show as liked, otherwise not. If we once again look at the puppies data in the browser, you can see that the puppies liked by User number one is number two, Chase, number three, Leah.

you can see that the Puppy liked by User number one is number two, chase, number three, Leah. Um, and that's it. So refresh the page. And if I scroll, chase and Leah are liked and none of the others are. And just to be super clear, if I open the database sqlite file here, I have a puppy stable. So for example, Ross is number five and I have a puppy_user pivot table. Let's create one more where the user is one.

and I have a puppy_user pivot table. Let's create one more where the user is one and the puppy_id is five AKA Ross. Okay, I will save that. And so when I refresh the page, I'm expecting now Ross to also be liked since I've added it manually in the database refresh. Let's go check us. Hey, let's go in the next lesson. Let's go and do that. Implement the real short list from the API data.

Let's go and do that. Implement the real short list from the API data. And while we write it, we'll also take care of the new puppies form so that when we submit a new puppy, we add it to the database in the Laravel app.

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