Client-Side GraphQL in React Querying Data Solution
Transcript from the "Querying Data Solution" Lesson
>> Speaker 1: Welcome back, hopefully everyone had enough time to write a query for the pets react page to Fets and Pets, and if you went the extra step you might've even added some pets based off the pet type in our graphical schema, to the sense so you can actually see some pets show up on the page.
[00:00:17] If you didn't get that far, don't worry, I'm gonna walk through it right now. All right, first thing first is let's figure out what query we're writing and go ahead and pass it to our use query. So in order to do that, what we'll do is, let me just comment this stuff out just in case it's broken on my version.
[00:00:35] What we'll do is we'll go to the app here and, let me refresh this. Looks like I've still got stuff broken. Yeah, pets not defined. Get rid of that.
>> Speaker 1: Cool, so we'll go to the Apollo dev tools. Sometimes you've gotta refresh it. There we go. And if we click on the Docs, we can see Query.
[00:01:01] And we wanna get the pets queries. So that's the name of it, pets. It takes optional arguments, pets input and it returns an array of pets. So that's the one that we're gonna do. I already have it here. So what I like to do is I like to just go ahead and write my query in here and get it all ready.
[00:01:16] So I'm gonna give it a operation name of something called like allPets. You can call it whatever you want. And then I wanna put my query in here and the important things, oops, this thing is all formatted for me. There we go. Why is this acting so weird?
[00:01:34] Wait! [SOUND] pets, there we go! The important thing is if we only ask for one thing it's gonna be the ID. Like if that's the one thing you ask for, make sure you get the ID back. And remember because we need that to cache, because without this what Apollo's going to do, it's going to use the path to the node based on the query as an index to store it, and that is a lot harder for Apollo to do automatic updates when you do things like mutations, because it's gonna be a different path.
[00:02:09] So I highly recommend always setting down an ID. Otherwise, you'd have to update that yourself. So do that. Let's get a name, let's get a type and let's get the image. So execute that, empty array. That means it didn't break, so that's good. And I was gonna copy that query.
[00:02:25] Now I'm gonna go back to our code and I'm gonna make a query. What most people do is the convention is, if you ever use something redux or anything like that, you kinda name your queries using all caps, and underscore. So, I'm just gonna name this the ALL_PETS.
[00:02:45] Query like that.
>> Speaker 1: And I'm just gonna paste in my query.
>> Speaker 1: Boom, so now we got ALL_PETS, we got our pets here. And I can go down to useQuery. So again, this is a hook but you don't really need to know that it's a hook. Just think of it as a function that takes a query.
[00:03:04] In this case,ALL_PETS. And it's just gonna return an object that has the data. A Boolean, if it's loading or not. Because this does happen asynchronously in the background for you. And I said the background, because you don't have to do this. There's no await, you're not waiting for this to come back.
[00:03:21] And that's why there's a loading property here, cuz this could be happening in the background. And just like in React where you do set state, what happens is once this promises resolve and there's no error, the data gets set which causes this property to be updated with the correct data which causes a re-render of this entire component.
[00:03:41] So this entire component re-renders whenever any one of these states used from a hook is changed. And that's what causes a re-render. So when data is changed because your query was resolved in the background, you're gonna get a re-render, and now data will have some data, and loading will be false.
[00:03:59] And if you don't have any errors, this won't be anything as well. But we need to handle that because if we just try to use data right now, it's gonna break because the data will for sure be undefined if loading is false because it's still loading, so we have to handle that used case.
[00:04:15] If you looked up top you might notice there's a loader component here, so we can just copy that and you can do something like, if loading, you can just return that loader component like that. And that will do a loading for you. And then you just need handle errors.
[00:04:36] If there was an error, you can return whatever you want. In this case, I'll just return like a P tag that says error, something like that. So we handle those use cases. And then now for data, data is going to be the entire response. And remember all graph kill objects return on a data problem.
[00:05:00] And then everything after that is whatever is in your query. So that means we're gonna have data.pets. We're going to have pets here. And if you don't want pets, then you can call this whatever you want, and then it'll going to be data dot whatever. That's where aliases come back in.
[00:05:16] So in this case, I'll just keep pets. Got data.pets. I'll go down to our pets list as pets like this, and as data.pets. Everybody following me so far? All right. Make sure your server is still on, everything is still good. Go back to refresh. If you don't get any errors then you did good.
[00:05:42] Now if you want to actually see something show up on the page, then you can go to dv.json and based off on, this thing opens back up. There we go, based off on the pet type which is here. So, ID, a name, owner, image creator, all this stuff.
[00:06:07] You can just copy this, you can go to pets.json. You can just make some pets, right click. So we'll move this over.
>> Speaker 1: There we go. So you can just hard code a lot of this stuff. I'm just gonna make this appropriate json. There we go. So for an ID, you can just put whatever you want, it's just an ID, it doesn't matter.
[00:06:32] For a type, I'm just gonna put dog. For a name, moose, owner, don't need that. Image, don't need that, created that. Sure sometimes out there, where you can make a few of this. So am going to copy that, make another one, make another one. Make this one a cat, give a different ID, give that one a different ID.
[00:07:07] There we go. Cool. Save that, have to restart the server probably. And if we go back and refresh this, we'll get some pets.
>> Speaker 1: Everybody following me so far? Who got tests to show up? So everybody understand the concept of having to handle the loading and error state.
[00:07:38] Right? If I were to comment this out right now, our whole applet break. completely broke and it's probably broke because. It's saying can't read doc pets of undefined or something like that. Yep. Can't read pets property of undefined. And that's because, it's trying to read pets of data, but data's undefined.
[00:08:02] And data's undefined because loading is true. So, your initial reaction might be able to go in here like, I'm just going to create a default state for data. Well, don't do that, just handle the loading case instead. And the same would go true, if there was an error.
[00:08:16] So, if I kept the loading, but didn't handle the error, and I for sure had an error here like that which is not a valid GraphQL query, it will probably also break, right? Can't read pets or undefined. That's because I have an error. And you know you have an error if you've got like 400 bad requests, and if you go look at the network tab you can see that it failed right here.
[00:08:39] The errors array, and it says cannot query field on type pet. Did you mean type, it even gave you a suggestion, look at that. Like that's what you meant, you actually meant that. That's actually a really good feature, I forgot GraphQL had that. That's really dope.
>> Speaker 1: Cool, so you fix that, handle your error case, good to go.
[00:09:02] Definitely wanna show a better error than that, but you get the point, pretty good.