Showing a grid of events is a great way for someone to browse, but once one catches their attention, they want to dig in for more info, or maybe they want a way to share a direct link to that event. Either way, we want to be able to have a page that requests an individual event, not a whole list of them.
We have some flexibility in how we request our data with the Appwrite SDK, where we can use the Get Document endpoint to pass in a single ID and get all the data for that particular event. This will allow us to work together with our router to dynamically get that value based on navigation and look up that individual event.
We’ll make this work by first requesting a single document by passing in a static example ID. Later, we’ll use the router to get our individual event’s ID dynamically. In order to clean things up, we’ll see how we can start to refactor and abstract some of our data transformation logic as well as how we can use Appwrite’s included Types to make sure we’re fully type-safe when working with Documents.
What You’ll Learn
Instructor: [0:00] Getting a list of all the documents inside of your collection or database is a great way to get all that data inside of your application, but it might not be that efficient if the only data you need is for one document or a single event for a page.
[0:12] With the Appwrite Web SDK, we can use the getDocument endpoint to get a single document from our collection. It's going to work pretty similar to how we listed our documents in the past lesson, only we're going to use the getDocument method, and this time we need to additionally pass in our document ID.
[0:26] This time, we're going to be working out of the event ID file, where we can see that we have a pattern that you might recognize some from frameworks like Next.js. We'll get back to this later when we're talking about how we're going to dynamically get our event ID into our component, but for now, let's set up our initial request.
[0:42] Now, similar to the last lesson where we created a function to get all the events, let's head over to libevents where we're going to create a function to get a single event by its ID. I'm going to export a new async function called getEventsByID, where our first argument will be an event ID, which will be a string.
[1:01] Because our code is going to be pretty similar to getEvents, I'm going to simply take this first line of the list documents, and I'm going to paste it into getEventByID, where we can see that the major difference is going to be the method we use, and we're going to additionally pass in that document ID.
[1:15] I'm going to replace list documents with getDocument, and if I then head to the end of this method, I'm going to pass in my event ID as the last argument. Of course, we're not going to have a list of documents, we're going to have a single document. I'm going to just replace that with document.
[1:31] Similar to the getEvents function, we're going to run into issues with the type of that document. We need to create a new event where it's typed as a live event.
[1:40] Now, because I know that in the future I'm going to need to do this for different functions, I'm going to now abstract this so anytime I have a document, I can easily get the event from that document. I'm going to create a new function called mapDocumentToEvent. You can tell that I'm not exporting it, and it's not async as I'm not doing any requests inside.
[2:00] I'm going to take this code where I create this new event, paste it inside of my map function, where the argument to this is going to be my document. Now, because we need to type this document, we can grab this document type from Appwrite. I'm going to import actually models from Appwrite, where this models is going to include that document that we can use for the type.
[2:21] Then on my actual document argument, I'm going to type that out with models.document. Now that we have this mapDocumentToEvent function, we ultimately want to use it.
[2:31] First off, we can head back up to our getEvents function, where I'm going to replace this entire block with this map function. What's going to actually happen is for each and every one of these documents, it's going to go through and run this function, and it's going to ultimately return one of these event instances.
[2:48] Before we move on, we can check that our home page is still happy, where we see all of our events. What this means is I can do the exact same thing with my getEventByID function, where I'm going to return my new object with my event, where I'm going to run that map function, and I'm going to pass through that document.
[3:04] Now we can actually start to use getEventByID. I'm going to head back to my event page, and I'm going to import getEventByID from @libevents. Again, similar to the home page, we're going to use useEffect and useState in order to make our request and handle having that event data to pass into our UI.
[3:22] Let's import useEffect and useState from React, where I'm going to set up my useEffect instance, where for now, let's set an empty dependency array. Later, we're going to come back and actually set this as the event ID. For now, let's create our new async function called run, where we're going to self-invoke that.
[3:43] Now, let's run our getEventByID function. Let's pass in constant results is equal to await get event by ID. Now, let's find an ID that we can use to test this out.
[3:53] Back on the home page, I'm inspecting my network requests. Let's just grab the ID of the first item, where I have the six four value. Let's pass that in as the ID temporarily, just to see that this works. I'm console log out my results. We're back on the individual event page, we can see that I get my results where that includes my event and all the data related to it.
[4:15] Now, we're going to set up our new state instance for our events, where as soon as we have our results, we're going to pass back our event as our new state. Of course, we can now get rid of that original static data that we were importing from our local project. We can also console log out our image as we're currently not supporting an image in our database yet.
[4:40] We can see that we're successfully getting that dynamic data into the page. To make sure our types are in place, let's head up to our state instance, where we're going to add our Livebeat event or undefined and import our Livebeat event from at lights events. Now, let's dynamically get this event ID from the router.
[5:02] We're not going to dig too deep into how this router works, but if we look at this last route, we can see that we have /event/event ID, meaning this is going to be a parameter that gets dynamically placed based on the value of this parameter. If you want to learn more about the router we're using, which is Wouter, check out the link inside the lesson description.
[5:23] What's going to happen is our router parameters are going to be passed in as a prop called params. Inside of that is going to include our event ID. For now, let's actually type that out, or we're going to have that object that includes params, where the params are going to include our event ID, which will be a string.
[5:39] Before we move on, let's console log out those params, just to make sure everything works. We can see on our page, we get that event ID of 1234, which is currently set in the URL. Now, if I grab this ID that I'm currently using, and pass that inside of the URL, we can see that once it loads, I get that as my event ID.
[5:58] Let's take our params, and I'm going to replace that static ID with params.event ID. What I'm also going to do is I'm going to add the params.event ID as a dependency of useEffect.
[6:10] Should that value ever change, it'll automatically kick off a new request to update the event data. Back inside of our page, we can see that when we refresh, everything is still working as expected, which it should be because we have that same ID.
[6:22] Let's see if this still works if we try our other pages. Now back inside of our home page, this link is currently pointing to that 1234.
[6:30] To start off, let's make this a dynamic value. Let's change this to template literal tags, where instead of that 1234, let's pass in the event.$ ID. While we're here, it's usually also a good idea to make sure you use an ID as the key as names could sometimes conflict, but IDs should always be unique.
[6:49] Let's now open up our home page and let's try going to eats and beats, where we now see eats and beats. If we go back, and now to DJ electric, we can see that we get the data for that event.
[6:58] By using the get document method, we were able to easily pass in that event ID, where we could grab that from the actual page, the visitors on and we can get that individual event data. Now that we're listing out all of our events, and we can even see them individually, what happens when we get past October 31?
[7:12] Did we just run out of events? I don't think so. Let's see how we can use the add event form to dynamically add new events to our page. We'll see how we can use the Apprwrite web SDK to not only read existing data, but write and create new data.