This course has been updated! We now recommend you take the Intermediate React, v5 course.
Transcript from the "Refactor Details" Lesson
>> Let's move on to details and make use of our API responses. So we're gonna pop over to Details.js. You can see there's already some fun errors waiting for us. We are going to rename this to Details.tsx. And now we get a ton of errors, right? But here we are.
[00:00:21] This is the game of Whack-a-Mole TypeScript errors and if you've written any TypeScript before, this feels very familiar. So carousel and error boundary won't fix right now, these won't get fixed until we fix those files. So just go ahead and ignore those ones for right now. Up here at the top, we're going to import pet[API]Response and Pet from our newly minted ./APIResponsesTypes.
[00:00:55] Okay, one thing that we can do here that makes things a ton easier, we don't have default state for all of our animal breeds, city, state, description, name, images, all these things. That's why this is so mad right now. So if we just give it a default state for all these different things, then it's gonna know immediately, okay, I already know what these are, I don't have to retype them later.
[00:01:18] Okay, so showModal, we got that false. And again, I don't have to tell it that loading is a Boolean, it knows because I gave it true or false, it's like, that's a Boolean. So I'm just gonna give it a default state for everything and then it'll just know what they are.
[00:01:34] So animal is just an empty string, but we actually wanna type this a little bit further, we wanna say this is actually an animal. Cuz we know it's actually one of those enumerated types that we created, so let's import animal up here well. On line seven, I also added an animal import.
[00:01:53] So now, it'll make sure that animal stays, bird, rabbit, reptile, and doesn't end up being something else. Okay, and then the rest of these, we're just going to say breed, empty string, city, empty string, state, empty string, description, empty string, name, empty string. And images, we're gonna have it be empty array, but we wanna tell it what kind of array it's gonna be.
[00:02:23] And it's a homogenous array, right, it's gonna be just strings. So we're gonna say as string[ ]. And now, notice all of these type errors down here in line 36 are gone, because now it knows what all of these are. Description, I know that's a string. I know that images is a string array.
[00:02:50] So that's pretty cool. So that's what this as word means, you're just basically saying, I'm giving you an array, but I'm actually going to give you something even more specific than array. It's an array of specifically strings. Just general advice for working with arrays in TypeScript, it's much easier if you make your arrays homogenous, right, so they're not mixed types.
[00:03:17] I think in general, that's kinda how we mostly operate cuz that makes sense to us logically, but it makes it very explicit when you do that in TypeScript. It's possible to do other things, but I'll suggest this where possible. Okay, up here, We need to type the props, right, cuz this gets some props as well.
[00:03:43] So we have Component here and we need to give it some typing for its props. So you can see up there on my tooltip, I have P, which stands for props. We can give it types for that. We can actually give it the typings for the state. If I hadn't done this right here, we'd have to give it typings for the state, but the good news is we don't have to because I did that here.
[00:04:06] Same thing, if I gave it default props, we wouldn't have to give it props typings either. But we don't wanna give it default props, so we're not gonna do that. Instead, we're gonna give it these parameters. And we're gonna say, you can expect an object that's gonna have params and that params might have an ID on it, so id?.
[00:04:27] Because we can't actually guarantee what react router is gonna give back to us, we actually have to be defensive about that. So we might get an id back, which is what that question mark means, it's optional. And if it does get an id, then that's gonna be a string.
[00:04:47] Now, I'll see people as well say, interface Props, or iProps, people like to put the i there, I don't care. But the I stands for interface, right? And you can say params ( id?) string. Some people will only do it this way. I'll generally do this if I have a lot of props.
[00:05:20] When I don't have many props, I'm quite lazy and I'll just put it directly in there. So I'm fine with whatever you choose to do, we'll do it both ways. So, I'll do it that way. Okay, So here we are. This here ends up being an any, it's like I don't know what that is.
[00:05:47] So any type is your enemy in TypeScript. An any type is basically like, this could be anything and I refuse to tell you anything about it, which defeats the purpose of TypeScript, right? You want no anys in your code as much as possible. And we've actually turned it on so that we say, don't allow any in here, get that any business out of here.
[00:06:09] So what we can do here is we can actually wrap this in parentheses. And then we're gonna say, whatever this comes back as, we expect it to be a petAPIResponse. And now, we know that this what it got back was a petAPIResponse. Now, you can still technically get runtime errors here, right, because what happens if your API changes shapes, right?
[00:06:37] But that's just the nature of computing systems, right, we're not gonna solve that here. Okay, That's fine, this is good. This one's a fun one. So window.location = blah, which I have been using since literally I can remember the first time I wrote browser-based code. It's actually technically not the API.
[00:07:01] It's a hack that I think they threw in Internet Explorer 7 or something like that, I don't know, some ancient browser, and everyone's like, well, I guess we're doing this now, and that's why this works. But technically, the API is actually href =, window.location.href =. And now this works, because it's actually using the correct API.
[00:07:29] Okay, So this is all looking much better, we're getting far less errors. UseParams here, you might just, I expect this to be a, And what I'm using out of this is I'm going to get an id string out of this. Okay, and then we know that we expect to get id into here, which is going to match up with this type up here.
[00:08:09] Cool. Any questions about any of this? I think at this point, we are done with details. Obviously, these two are still erroring, but we'll fix those and then this will stop erroring there.
>> Yeah, I have a quick question.
>> Yeah, please.
>> About, let's see here, about that API call.
[00:08:34] I know you're saying about competing systems and the potential for the shape of that object to change. Is there any type of error handling you would recommend to be defensive about that?
>> Sure, this is an async function, which means you can wrap it when you call it with try catch.
[00:08:54] So you could do it that way. So let's say you just do try blah, Catch e, right, and so on and so forth. That would be the immediately obvious way to do it. The other thing that we've actually technically already done is this is wrapped in an error boundary, right?
[00:09:18] So if there's an error here and then componentDidMount, it's actually gonna hit our error boundary here, right? And then this will show a nice page, like there was an error on this page, we're gonna redirect you back to the homepage. That's the react way of doing it. But it's contextual to how you wanna handle those sorts of situations and how unreliable your system is, or, I guess, what tolerance you have for unreliability in your system.