How to Query for GraphQL Data With Limits and Filters
With our `listing` query now prepared and available in our GraphQL API, we'll begin building the page shown in the `/listing/:id` route of our client app.
Get the project source code below, and follow along with the lesson material.
Download Project Source CodeTo set up the project on your local machine, please follow the directions provided in the README.md
file. If you run into any issues with running the project source code, then feel free to reach out to the author in the course's Discord channel.
This lesson preview is part of the TinyHouse: A Fullstack React Masterclass with TypeScript and GraphQL - Part Two course and can be unlocked immediately with a single-time purchase. Already have access to this course? Log in here.
Get unlimited access to TinyHouse: A Fullstack React Masterclass with TypeScript and GraphQL - Part Two, plus 70+ \newline books, guides and courses with the \newline Pro subscription.
[00:00 - 00:18] Our GraphQL API is now prepared to have us query the listing field to get information for a certain listing. With that said, we'll begin working on the client portion and now create the listing page for when a user visits a listing route with an appropriate ID.
[00:19 - 00:31] The UI for the listing page will look as follows. The listing page shows the details for a certain listing as well as provides the capability for a user to book the listing within certain dates.
[00:32 - 00:55] The user is able to see the details of a listing which consist of the listing image, location, title, host and the host avatar, description as well as the bookings made to the listing. On the right hand side, the user is able to book for a listing by picking the dates they would like for the listing to be booked and the price per day is shown at the top of this booking card.
[00:56 - 01:05] The component breakdown of this page will be as follows. The UI for the listing details will be grouped within a component that is to be called listing details.
[01:06 - 01:18] The listing bookings component is will be responsible in showing a paginated list of bookings for this listing. The listing bookings component will only be shown if the user is viewing their own listing.
[01:19 - 01:32] The capability to create a booking will be part of the listing create booking components. When the user selects dates in this component and clicks the request to book button, a modal will eventually be shown.
[01:33 - 01:50] This modal will be rendered as the child component of the listing page and will allow the user to pay and officially book the listing. We'll create this modal later on and for now just focus on building the listing details, listing bookings and listing create booking components.
[01:51 - 02:06] Finally, when the query for listing information is in the loading state, the page skeleton component or the shared page skeleton components we've created before will be shown. The first thing we'll do is create our GraphQL query document.
[02:07 - 02:43] We'll create an index file within a listing folder that is under the lib Graph QL queries folder where we'll construct the listing document. And we'll export this soon to be created document from the GraphQL queries index file.
[02:44 - 03:10] Our client will pass to the listing query an ID argument, a bookings page argument to reference the page the user is viewing for their bookings list, and a limit argument to constitute the amount of booking objects to be shown for a single page. And we'll practically query every single field within the listing GraphQL object.
[03:11 - 03:36] We'll query for the listing ID, the title, description, image, host, and the host object will get the ID, name, avatar and the has wallet field. We'll query for the listing type, the listing address, the city, the bookings of this listing.
[03:37 - 03:53] We'll get the total amount of the bookings as well as the results. And from the results, we'll try to get the ID of the booking, the tenant of the booking that is to say the person who's made the booking, the person's ID, name, and avatar.
[03:54 - 04:09] And the check in check out fields of the booking. We'll get from the listing object the bookings index field, the price, and finally the number of guests.
[04:10 - 04:22] There is one small, thick mistake we have here. If I recall correctly, the check in and checkout fields are part of the result array being returned within the paginated bookings list.
[04:23 - 04:35] Total gives us the number of bookings and result contains all the information for a single booking. If we want to verify this, we can always look in the schema definition of our GraphQL API, but I believe this was what we had.
[04:36 - 04:53] With the GraphQL listing query defined, we can auto-generate the corresponding TypeScript definitions using the codegen schema and codegen generate scripts available in our app. We'll run the codegen schema script to regenerate the schema JSON file in our client application.
[04:54 - 05:36] and we'll run the codegen generate script to regenerate the TypeScript definitions from our GraphQL queries and mutations. We'll now build the listing page in the listing section component that we've established before.
[05:37 - 05:46] The structure of how we make our query will be very similar to how we set up the user page. We'll import the use query hook from React Apollo.
[05:47 - 06:19] We'll import the listing GraphQL document from the lib GraphQL queries folder. We'll also import the auto-generated TypeScript definitions for the data and variables for the listing GraphQL query.
[06:20 - 06:39] We'll run the query when the component mounts with the use query hook and attempt to return the loading, data and error states of our query request. We'll also pass in the auto-generated type definitions for the data to be returned from the query and the variables that are expected to be passed in.
[06:40 - 06:58] The listing query we make here expects us to pass a few variables such as the ID of the listing that is to be queried, the booking page the user is viewing and the number of bookings to be returned in a page and in other words the limit of our pag ination. The ID will come from the route that the user accesses.
[06:59 - 07:22] We'll get the ID peram from the route from the match prop available in this component since this component is rendered from the route component in React Router. So we'll import route component props from React Router.
[07:23 - 08:10] We'll declare the interface for the params in our route as match params which will consist of an ID of type string and we'll access the match prop available in the component and set the ID variable of our query as match.perams.id. When the component mounts for the first time the page number for the booking should be one or that is to say the first page.
[08:11 - 08:31] So to instantiate this value and have it tracked as component states will import the use state hook from React. We'll use the use state hook at the top of the component and destruct a booking 's page state value and a set bookings page function we'll use shortly to update the booking's page value.
[08:32 - 08:46] We'll initialize the state booking's page value as one and declare it as the value of the booking's page variable in our query. The limit variable is how many bookings will want limited for a certain page.
[08:47 - 09:04] We'll define a constant above and state a page limit of 3 and we'll declare the value of the limit variable to be this page limit. While our listing query is being fetched we'll want to show the shared page skeleton component we've set up before.
[09:05 - 09:23] So we'll import the page skeleton component from the lib components folder and we'll say when the query is loading we'll want this page skeleton component to show. We'll want to wrap the page skeleton component displayed with antdesigns content component from the parent layout component.
[09:24 - 10:05] So we'll import the layout component from antdesign and wrap our page skeleton with content. If our query ever errors we'll want to show the page skeleton component with an error banner being shown above it.
[10:06 - 10:28] So we'll import the shared error banner component we have in the lib components folder and we'll render it in addition to the page skeleton component if our query was to ever error. We'll place a description of the error along the lines of this listing may not exist or we've encountered an error.
[10:29 - 10:42] Let's try again soon. At this point if our query finishes loading and no error arises this means our query has resolved and data is now available.
[10:43 - 11:07] We'll get the listing object from data and the bookings object from listing available to us. With the expected data now here we can begin to build the child components in our UI and surface the information we want.
[11:08 - 11:40] We'll build the child listing details component and child listing bookings component and render it in this parent listing component in the next lesson or so. ( Laughter )