In the last lesson, we set up our new database and now it’s time to read our Documents and list them out in our project. This is where we’ll start working with the Web SDK to programmatically request those event Documents and dynamically pull them into our application so that when someone adds a new one, our application will show it right away.
We’ll first start out by learning how to use the Databases service. Once that’s ready to go, we’ll use the List Documents endpoint configured to pull the data into our application from our previously created Database Collection. We’ll then define a new Type for our data to make sure we’re working with our event safely throughout the app.
What You’ll Learn
Instructor: [0:00] All right. We have our database set up and we have a little bit of data inside to work with. How can we now start to bring that data inside of our application?
[0:07] Jumping back inside of our code, we already have the core client set up for Appwrite. When trying to work with querying these documents using the SDK, we can see that we're going to want to set up a new instance of databases where we'll use that to query our documents.
[0:20] First, we're going to import databases from Appwrite where underneath our client, we're going to export a new constant of databases, which is going to be a new instance of databases, where then we just need to simply pass in our client.
[0:34] Now that we have our databases instance ready, let's head back over to our Home page, where inside we're going to start by importing databases from at lib Appwrite. Now, we're going to be making a request on the client of our application.
[0:49] To do that, let's import the useEffect hook from React, where at the top of our component, I'm going to create a new instance of useEffect, where inside, we're going to pass in a dependency array that's empty, meaning it's only going to run once when it's mounted.
[1:04] From here, we can start to run the code that's going to make our request. Instead of using then, I prefer the await syntax. What I'm going to actually do is create a new self-invoking function. I'm going to simply call that run, but I'm going to invoke it by passing in the parentheses at the end.
[1:20] I'm going to say await databases, where I'm going to use the list documents method, where I'm going to pass in two arguments. One being the database ID and the other being the collections ID. Now similar to when we ran into our project ID, this isn't going to be an ID that I'm going to want to have to reference over and over and over throughout the application.
[1:40] What I'm going to instead do is I'm going to use environment variables for each of these values. Inside of that env.local, I'm going to create a new set of variables where I'm going to create my events database ID, but then I'm going to also create my events collection ID.
[1:55] Now if you notice, I'm prepending both of these with events because of the fact that I might be using a different database or a different collection if I'm doing something else within this project.
[2:04] Heading back to the Appwrite dashboard, the first thing I'm going to want to do is copy the database ID, which you can find inside of the databases section right next to the header here, paste in my database ID, and then navigate to my collection where I'm also going to be able to find my collection ID, where I'll similarly paste that into my file.
[2:21] Now from here, I'm going to want to copy these into my home page where I'm going to first set up my import.meta.env.my database ID. I'm going to go ahead and copy that entire thing and replace my collections ID and then replace the word with collection to make sure it's using the right variable.
[2:36] Now, let's put that into a new constant. Let's call that results where let's just simply console log that out for now to see results. When I open up my application, we can see that I have my results logged out. I currently have a total of three documents, which sounds about right. We can see all the documents that I have, including all the data that goes along with it.
[2:55] Now one thing to notice that we are getting logged out to results. That's because we're using strict mode for our application. Technically, it's going to run twice in development mode.
[3:03] Now that we have these results, let's now capture these documents and inject them into the page. I'm going to useState to do this. I'm going to import the useState hook. Where at the top of the component, I'm going to create a new constant where I'm creating a new instance of state called events.
[3:18] I'm going to also add my setter of set events, where I'm going to set that to useState. Now at this point, we can get rid of our original events import since we no longer need that local data.
[3:28] Once we have those results, we can now set events using results.documents. Now as soon as we refresh the page, we can see that we now have our data getting injected in the page. We did lose our images, which we'll come back to later in this course.
[3:42] We can see that we are now getting that dynamic data from our Appwrite database. Let's head back to our code where we have a little bit of cleanup to do where we can see that we're getting some squiggly lines around some of the code. That's because we need to actually start to think about typing out our events.
[3:56] Since I know that I'm going to be needing to use these types in more locations than just this home page, I'm going to create a new file for this. Now because I've not yet actually defined any types, I'm going to go up and I'm going to create a new folder under source called types. Inside of that, I'm going to create a new file called events.ts.
[4:13] Inside, I'm going to export a new interface called live beat events. Live beat event is a little bit long, but I don't want to use the word just event as I don't want to have any collisions with the default event type. Inside, I'm ultimately going to have my name, which is a string. I'm going to have my location, and I'm also going to have a date.
[4:33] If we look back at the data, where currently I'm looking inside of the network tab, we can see that we also have an ID, which is going to be handy throughout our application to make sure that we're always identifying the exact event that we're talking about. Now, because I know that I'm going to want to use that I'm going to also add my dollar sign ID, which is also going to be a string.
[4:51] Now back inside of my home page, I'm going to import my live beat event from at types/events. Now to start using this type, I'm going to go down to useState where I know that my events is going to be an array of events.
[5:06] I'm going to type this out where I'm going to specify an array where it's going to be an array of live beat event. We also know that by default or to start, it's going to be undefined. I'm also going to specify that it could be or undefined.
[5:17] Now we can see that starting to clear up some of our issues, including events.length. If we scroll down, we can even see the map statement. We do see that we're having issues with this image. It's because we don't yet have that defined. We're not going to do that until later lessons. I'm just going to comment that out for now.
[5:32] If we go back up to the top of the file, we can see that we are still actually having issues with this results.document. The reason is the type that's coming back with each of those documents conflicts with our live beat event, because by default, it doesn't have those named pieces, including name, location and date.
[5:48] Now, instead of trying to fix this here, what we'll actually do is start to think about how we can clean up this method in the first place, because I don't want to be importing this metadata environment variable in every single time I want to try to get these events. What we'll do is actually abstract this functionality, where we can then manage the event type.
[6:06] Over inside of my lib directory, I'm going to create a new file called events.ts. I'm going to export a new async function called get events, where I'm going to simply copy the same line that I had for the list documents method, paste it directly into my file, where the only thing that I'm interested in right now, the results is the documents.
[6:24] I'm going to go ahead and destructure that. As my return statement, I'm going to return an object with a property of events, where I can start to define these documents that I'm going to return. Now, as we know, we're probably going to run into issues again, because this is going to be an array of the Appwrite document type, where it doesn't have the information we need, and we want it to be a live beat event.
[6:42] There's probably a better way to do this in TypeScript. What we can do for now is we can use the map method, where I'm going to say for each document, I'm going to create this new function, where I'm going to create a new constant called event. I want that to be a live beat event.
[6:57] Now that means I want to also import my library event from types events, but I want this event to be composed of all the information that makes up a live beat event. That's going to be my ID, my name, my location, and my date.
[7:11] As we know, these are going to be the same keys that are actually on the document that comes from our database. For each of these, I'm going to simply grab that name. We're going to make it a reference to document.thatkey. Then we'll ultimately return that event from this map statement where our events will be an array of our live beat events.
[7:28] We can see that we still have issues with document and databases. Now that's because we've never even imported databases to begin with. We can make sure that we import databases from our lib Appwrite.
[7:40] Now we can see all of our errors are resolved within getEvents. Now, let's actually use getEvents. I'm going to replace this databases lines with getEvents. I'm going to import that from lib events. Then I'm going to take events, I'm going to replace this results line with const, the structured events equals await get events.
[7:59] Then I can simply pass set events with my events value. Back inside the application, we can see that everything's still working and we're dynamically grabbing our event data from App,write.
[8:10] Next, we have a list of all of our events but we want to make sure that we have individual pages for all of our events. Let's see how we can get an individual document by its ID using the web SDK.