Client-Side GraphQL with React, v2

Wiring Queries to the UI

Scott Moss

Scott Moss

Superfilter AI
Client-Side GraphQL with React, v2

Check out a free preview of the full Client-Side GraphQL with React, v2 course

The "Wiring Queries to the UI" 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 demonstrates how to implement a create issue functionality in a web application using GraphQL and Apollo. He explains the process of making a mutation request to the server, handling the response, and updating the UI to display the newly created issue without having to refresh the page.

Preview
Close

Transcript from the "Wiring Queries to the UI" Lesson

[00:00:00]
>> Scott Moss: Okay, so now what we need to do is need to make this work. So if you click create issue or New Issue, this modal comes up. You can type in an issue, a description, and click this button. And not only do we wanna create an issue, we want it to show up on the page immediately.

[00:00:16]
And there's a lot of ways you can do that. Some of them are very library specific, and I wasn't gonna do it that approach cuz maybe production you would do that, but also it's so specific to the library that I don't think it's worth showing cuz you can pick whatever library you want and they're all very different.

[00:00:33]
So I'm gonna show you how to do it outside of the library. I think just knowing the mentality around, how this is working, is more useful than walking through how the framework would do it. But I could also walk through the framework example as well, just to kinda show you what it would be like.

[00:00:50]
But it's basically just like Redux. It's you either do the Redux way with the framework, in this case, @urql, or you just refresh the whole query, which is something React query would do. So we're gonna go to that approach, which I think is much simpler because otherwise you gotta understand normalized caching and local doing graphical queries on local data versus doing graphical queries on remote data is quite complicated.

[00:01:15]
So I kinda avoided it 'cause I think it's a little more advanced. But anyway, let's go make the create habit. Before I do that, I'm gonna push this up so people can have this so.
>> Scott Moss: Say, stash, gIt checkouts clients.
>> Scott Moss: Okay, so this will be on client /2, if you want to kinda see what I was doing, if kick off from there.

[00:02:00]
I'm just gonna go ahead and make a new branch right now, before I forget.
>> Scott Moss: All right, so now we're on client/3, and here we're gonna allow this onCreate to actually work, so let's go do that. So I'm gonna go to our notes just to make sure I'm staying on track with that.

[00:02:23]
>> Scott Moss: So for create issue, we already did the mutation before. So it's mostly what we did before with the create user except we have a create issue mutation. We know how the inputs work, we know how to do all of that. So we mostly just gonna do that and then tie that back into the same page, we were just on for the onCreate method and everything should just be hooked up already for you.

[00:02:47]
We just got to figure out where did those things tie in? And then more importantly, the last part is, we created it, but we'll have to refresh the page to see the new data. So how do we get the data on the page without having to refresh the page, which it would be kinda bad.

[00:03:03]
So let's do that. So like always, I'm gonna go to my Apollo server, I'm gonna clear this out,
>> Scott Moss: And I'm gonna use the mutation. I'm gonna click +, I'm gonna click createIssue, let me see, I need the id for sure. I need the name, I need the status, and I need the content.

[00:03:28]
I'm gonna go ahead and get all of those. Probably don't even really need the content, actually, just those three are probably fine. And as far as the arguments, I'm gonna click here and I'm gonna say yes. I want to be able to pass in content and name those are required.

[00:03:43]
And then you don't have to pass in the status cuz it defaults. It defaults to one so you don't have to do it so that's fine. So we're good there, get rid of this, there we go.
>> Scott Moss: And I'm just gonna copy this, but first I'm gonna rename this from mutation to CreateIssueMutation, like this.

[00:04:12]
So I'm gonna copy that.
>> Scott Moss: And then now I'm gonna go into our gql file, gonna make a new file here. And I'm gonna call it createIssueMutation.ts. And we're gonna do the same thing we've been doing from @urql/next, GraphQL.
>> Scott Moss: export const CreateIssueMutation = gql`, and paste that.

[00:05:04]
>> Scott Moss: All right, so there we go, got my mutation ready to go. All I have to do is import it and use it inside of our page, which is gonna be an app dashboard page.tsx. So let's go back there, we're gonna import it here.
>> Scott Moss: @gql, I'll just say CreateIssueMutation there we go.

[00:05:31]
So we got that, we already have useMutation at the top. If you don't import that from @urql/next, get the useMutation,
>> Scott Moss: Underneath I'm just gonna say, = useMutation(CreateIssuedMutation) here for the mutation. We're probably not gonna use these results, so I'm gonna give it a name. createResults, and then this is the actual creatIssue function.

[00:06:10]
>> Scott Moss: Okay, so, a couple things we wanna do here. I think I have the notes for exactly what, I'll make sure I follow that. First we wanna make the call to create the issue, I wanna make sure we pass in the issueName, that's here bound to this date, passing the IssueDescription that's bound to this date.

[00:06:30]
And then if it does not error out, we then want to close the modal and every set those dates. And then eventually we will need to figure out how to refresh everything, so well let's do that. So I'll say data. All right, what about color here? Result, I'll just call it result, otherwise it's data.data.

[00:06:51]
That's gotta = createIssue. We have that, we know we can pass in a name, which is gonna be issueName. We can pass in the content, which gonna be issueDescription like that. And then I can say if (result.data), I can say close the modal, which is passed in here and then just reset the states.

[00:07:22]
setIssueName(` `) and setIssueDescription(` `).
>> Scott Moss: Okay, everything else should be hooked up. [COUGH] Let me double check, yeah, onCreate is here, looks good. Let's give it a try, so if I go back to the browser.
>> Scott Moss: Refresh this, if I click new issue, if I click New Issue give it a issue, I don't know, clean my hoodies that I got Cheetos all over.

[00:08:09]
[LAUGH]
>> Scott Moss: I need to wash them, I can click Create Issue, and we'll see what happens. Either it error or nothing happened, let's see. Let's try this again, I don't see an error, so I'm gonna try this again. Create Issue, here we go. Okay, so it says, variable input.

[00:08:38]
So I forgot to call the actual variable input. It's very strict, right? So I just put an object in here like this, right? But really what it wants, it wants this. It wants input, and then it wants an object.
>> Scott Moss: But you see, it still gave me a 200, right?

[00:08:57]
So you have to look at the error messages, right? And in a realistic app, what I would have done, let's just go back, let's put this back here. What you would do is you would do this, right? You say, if (result.error) and then I can see that here.

[00:09:13]
So I would say console.log, or console.error (result.error). So let's do that, run that back. Go to the Console, and then here you go, I have it right here. Variable input of required type CreateissueInput was not provided. It's pretty damn specific about what you messed up on. You can't miss it, it's there.

[00:09:37]
So that's what I like about it. I know you guys didn't write the server, but I wrote the server. I didn't have to write that code, that's given to me for free, that error message, that type checking is done for free because that's what the schema says. So, I didn't show you guys the schema cuz you don't really need to see the schema.

[00:09:57]
And when you're working on client side only, you can't do anything with the schema, but you can explore the schema here. Obviously, this is what this is for, but if you click here, it will actually show you the entire schema for your API, right? So here's the actual schema.

[00:10:19]
Here's the fields on the queries, I can get all the issues, I can get this current user if I click on mutation you see I have five of them. I can create an issue that returns the issue type and create a user returns a user type, I could delete an issue returns an ID, edit, signin all these everything so here's the schema.

[00:10:41]
So you can take a look at this to get an idea, what it is you need to do. So for me, I just did the mutation on or I did the query on issues. I could clearly see that, this thing has an issue input. So I can see here that, this is what it's requiring.

[00:11:01]
So I don't have to guess, there isn't a lot of guessing here, is go here, and you can kinda figure it out. If you wanna see what it actually looks like in code, this is what it looks like. So on the server, if you take the server side cores, you'll be making this.

[00:11:12]
This is the actual GraphQL schema and the syntax that it uses to actually create the schema. What is it called? There's the SDL query. I don't know there's a word for it, acronym for it, for the GraphQL schema. I just call it the GraphQL schema, but I think it's called the SDL schema definition language.

[00:11:36]
I'm pretty sure that's what it's called, but nobody calls it that. It's just a GraphQL schema. So, yeah, you can look at that. But if you wanted to see it in a code, it's here, you can go to schema.ts, go to the one that's on GraphQL, not the one on DB, and it's here.

[00:11:53]
You can see it, it's a GraphQL schema.
>> Scott Moss: That way you can kind of see. So if I go and look at the issues query again, you can see query issues, it takes input. It needs an object with the input field and its type is this. I didn't give it an input field, I just gave it this type.

[00:12:12]
So it has to be an input field, that's what it's saying, right? If you go back and read that error
>> Scott Moss: It says variable $input of required type, CreateIssueInput, was not I'm sorry, I'm looking at the wrong query. It needs to be created, here we go. So this input is, it's got an exclamation, so it's not null.

[00:12:34]
You have to pass it, if you don't pass this input it won't execute. It won't even run your code on the back end, this has to pass. So what it's saying is, $input of required type CreateIssueInput was not provided or $input is this. It's saying you didn't provide this and it's required.

[00:12:57]
>> Scott Moss: So that's what it's saying, but all of that is just show you how you can look at the schema through Apollo. Even if it's API that you didn't make, you obviously you can't go and look at the schema like I just did here. But if you use Apollo Studio or anything like this, it'll do introspection on the schema and it'll pull it down, it basically will create documentation for you.

[00:13:24]
This what this is, right? It's creating documentation for you off the GraphQL schema. So you can see you can put any GraphQL url here, as long as it's public or if you have any headers, you have to pass it get access to it, as long as that API has introspection enabled.

[00:13:42]
It will send down all of its types and objects and everything like that, so the tooling can support it and create it. So this gets into something really cool which is called GraphQL Federation, where GraphQL API's can talk to each other and understand each other by introspecting to each other, and stitch schemas together to create one federated schema.

[00:14:03]
Backend, there's a whole other world. Frontend is just, all right, query language, that's cool. Backend, it's a graph, it's literally a graph. So it gets kind of crazy, but sorry that's that's my little tangent. Let's get back to it, so fix this issue by just putting this in another object, objects called inputs and doing that, so hopefully that fixes that.

[00:14:31]
And let's try this again, so now I'm gonna go here, I'm gonna click Create Issue. This time it didn't create the issue, but as you can see, we wouldn't know that, it doesn't show up on the page. But if I hit refresh, there it is. It does show up because we already wrote the query for this, way we're gonna run the query that does this and it the query runs when the page renders and refresh triggers a render, so it showed up.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now