Check out a free preview of the full Client-Side GraphQL with React, v2 course
The "Project Issues Queries" Lesson is part of the full, Client-Side GraphQL with React, v2 course featured in this preview video. Here's what you'd learn in this lesson:
Scott explains how to create a query to fetch data from a GraphQL server using Urql in a React application. He demonstrates how to define the query, import it into the app, and use the `useQuery` hook to execute the query and handle loading and error states. He also shows how to map over the data and render the results in the component.
Transcript from the "Project Issues Queries" Lesson
[00:00:00]
>> Scott Moss: All right, so yeah, that's the N +1 query problem querying nested data that's cyclic. You can have issues. If you take the server side version of this course, I'll talk more about that. Might even dive into some solutions, although it's a little more advanced. But we'll talk about a little more, cuz that's definitely something you have to do on the server side.
[00:00:19]
The client is the attack, the person doing the antagonist in that type of scenario where the server would be the one defending. So it's definitely on the server to figure it out. But let's get to it, let's make our issuesQuery. So that's kinda where we started. So I'll go back to that.
[00:00:38]
Let me get rid of this highly nested data, I don't want that. And instead, I wanna get the content, the ID, the name, the status. I think that might be it for now. I can't remember the component that I have once, but that's it for now. I'll get rid of the variables.
[00:00:59]
I'm just gonna use my UI here to help me do it. So I'll say, get rid of those arguments, I don't want those. And I'll call this issuesQuery. Remember, this name right here, it doesn't matter. So you do want them to kinda be just like functions in JavaScript, think of if you were making, I don't know, JavaScript in 2005 where everything was in one file in global.
[00:01:27]
You don't want these operations to have the same name. So you can name whatever you want, but try to give them different names to avoid any potential conflicts there. So I'mma copy that. I'm going to go over to our app. I'mma go to our GQL folder, make a new file here.
[00:01:49]
I'm gonna call this IssuesQuery, like so. I'm going to import it from either one of these cuz they both import from the same GQL. So I'm just gonna say GQL there. Oops, not gqk, whatever that is, and I'm going to export this. So IssuesQuery equals graph query, or gql tag, and then paste in my query
>> Scott Moss: There we go, getting our issues.
[00:02:31]
I'm gonna keep all these the same. My component is expecting these fields with these names if I renamed them. You have to appropriately go rename your components and the properties that they're looking for as well. So keep that in mind if you rename any of these. But I'm gonna keep them like this.
[00:02:47]
I think we're good here. And then now, if you go look at the notes,
>> Scott Moss: We need to go to app/dashboard/page, and this is the index page of the app, and here is where we're gonna do the query. But we're also gonna handle some of the error states and the loading states as well so you can kinda see what that would look like.
[00:03:14]
It's very similar to how you would do, like I use query from React Query or SWR, is very similar. They all kinda just copied each other, which is great for the community cuz we'd all benefit from similar APIs and interfaces. So let's go do that. So I'mma go back to my code, go to the dashboard, go to the page.
[00:03:39]
>> Scott Moss: There we go. And I need to import useQuery. So I'mma say, useQuery.
>> Scott Moss: Do I already have it? I already have it, useQuery use mutation. If you don't have it, then you can import it. I think we wanna import it from the next one now.
>> Scott Moss: Our goal, next, yeah, make sure you import it from the next one.
[00:04:09]
Although I think because we're in use client, the ones not from the next one, we're fine cuz we're doing use client. But just to be safe, make sure you import from the next one. The other reason I chose urql other than the name being cool as hell and it being easy to understand is that they actually are one of the only ones that offer full support for app directory.
[00:04:29]
Apollo had an experimental one. That's literally the name of the package. It was next experimental. And I was like, okay, that just means I'm gonna have to reshoot this course like two days cuz as soon as I go home, they're gonna release. The final one is gonna be different, and I'm gonna like, the course doesn't work anymore.
[00:04:43]
So I didn't wanna do that. So this one had full support, so we're using it. Okay, so we have that. We just need to import our query. So IssuesQuery. Actually, I should just be able to do issuesQuery like that. There we go. Got our issuesQuery, and then down here, I'm gonna make my declaration.
[00:05:07]
So I'll say, useQuery, like this, pass in my issuesQuery, like so. And then here I get back two arguments. One is an object, I'm gonna de-structure some things from there. And the second one is a function that you can call to re-execute the query. I'm just gonna call it replay.
[00:05:27]
So because what's gonna happen is, let's see if we got issuesQuery. Let me figure out that.
>> Scott Moss: Why I'm doing that, right? And he's an object, sorry about that. That makes more sense. So I need to pass in the query. Not that, there we go. Passing an object with the queries parameter, and then issueQuery.
[00:05:59]
But like I was saying, you're gonna get this function here that you can call again to rerun this query. Because unlike me, use mutation, when this component renders, this query is gonna fire immediately by default. You can stop it from happening, but by default, it's gonna fire immediately.
[00:06:19]
And if you wanna rerun it, here's a function you can call, and I'll rerun the same query, and we will use it. So that's why I'm making a declaration for it. So we got that. And then here we'll get the data, we'll get the error if there is an error, and we'll get fetching, which will be a Boolean if it's fetching, okay?
[00:06:40]
So we got those.
>> Scott Moss: And then basically what I wanna do is here, I'm mapping over this empty array. Instead, I wanna map over the data if there's data, and short error if there's error, and fetching if it's fetching. So let's do that. So I'mma do here. This is pretty much all the reactor gonna do for this course.
[00:07:04]
This is all of the rear. So I'm gonna say, if we're fetching and there's a component called spinner, it's probably already imported for you. If it's not, you can import it from, where is it at, spinner. Here it is, it's from @nextui-org/react. It's called spinner, should already be important.
[00:07:27]
So you can use that like this. So if fetching, and show the spinner like that. And then if there's an error we can say, error. And I don't have a fancy error component, so I'm just gonna put a div that says, Error.
>> Scott Moss: And then for here I wanna say, well, if there's data, and I wanna say, data.issues.
[00:08:01]
And I know it's issues because if I go look at my query,
>> Scott Moss: That's what it's called here, it's called issues. So it's data.issues. If this was something else, it'd be data dot whatever that is. So we got data.issues.map, I get the issues here. And then I'm just gonna look over the issue and pass it to the issue component.
[00:08:30]
>> Scott Moss: Cool, so we got that. You'll probably do this, you won't see any issues cuz you probably don't have any in your database cuz we haven't, unless you went into the API explorer, ran the create issue mutation and created some issues there. You probably won't see any here.
[00:08:45]
But that would have required setting up the auth and all that stuff inside of there. So which is basically what I have here, inside of mine I have this headers. And the reason I have issues on this, and you're not gonna see them when I go in. Let me close this so you can see what I'm talking about.
[00:09:03]
I have a JSON web token here on my Apollo server. And that's why when I do the issuesQuery, it actually gets the issues. But if you try to do it, you'll probably get unauthorization error or something. Yeah, you'll get unauthorized, like I'm getting now. So you probably will see that when we write this query, and we won't.
[00:09:26]
Well, if you're signed in, you won't see it, but if you try to do it here, you will see it. But when you go to the app and you refresh the page, it'll just probably just be an empty array, which means nothing will shown on the page. But if you run it in here, you're probably gonna authorize.
[00:09:42]
>> Scott Moss: Okay, so back to our code, let's make sure this looks good, everything looks good here. I think all this is still fine, let's run this. So I'mma go back to my app here, or refresh. There's my loading state, you saw those fetching. I don't see error, so I guess it didn't error, but I also don't see any issues because, again, my user doesn't have any issues, I can verify this.
[00:10:05]
I'll go to the Network tab, hit Refresh. And then what you'll notice is, you should just be able to go down here and click on where it says graphql, click on that. And you can see right here, I don't have any issues. It's empty array. I zoomed in too much.
[00:10:22]
There we go.
>> Scott Moss: So you should also be getting an empty array.
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops