Part of the appeal of our events site is not only being able to show cool events, but allowing others to submit their own events. But so far we’ve only worked with data that already exists in our database, how do we create data?
The Appwrite SDK gives us the ability to easily create a new Document by passing in our data. Additionally, the SDK provides helpers that make dealing with things like unique Document IDs easy. But part of the trick with creating new data, is we need a mechanism to input data, which is where we’ll see how we can read a form in React with Typed out data, so that we can pass it along formatted to Appwrite.
We’ll first learn how to create a new Document using the Appwrite SDK. This includes the ID helpers for generating a unique ID, formatting dates to the required format, and using our existing Types for that creation process. When passing along our Types, we’ll omit the ID which we’ll only get once the data exists in the first place. We’ll then see how we can dynamically grab data from a form, rather than hardcoding the input data, and open up access so that we have permission to create our new Document in Appwrite.
What You’ll Learn
Resources
Instructor: [0:00] So far, we've been using the Appwrite Web SDK to get data or read existing data from our database. What if we then want to actually add data or write new data?
[0:09] The Appwrite Web SDK offers the Create Document Endpoint where you can see a pattern where all the endpoints follow similar conventions, where here we're going to be passing in our database ID and our collection ID, where this time we're going to be using the Create Document method only this time the biggest difference will be we're going to be passing in a new document ID.
[0:28] Now, don't just sit there trying to write out a bunch of random numbers yourself. Luckily, Appwrite also provides a helper for this which we'll see later in this lesson. Now, we're going to start off directly inside of libevents, where what we're going to do is we're going to clone our getEvent by ID function. We're going to call this createEvent.
[0:45] Instead of passing in just the event ID, we want to pass in the full event data. We're going to call this, events. We're going to type this out as a LiveBeat event. Next, instead of getting a document we actually want to create a document.
[0:59] We're going to use that method of create document and with that method change we're going to also change how we're actually passing in the parameters, where currently we're passing in our database ID and our events collection ID which we want to keep as is, but we also have two new parameters that we want to pass in.
[1:17] First, we need to pass in a new unique ID for our document. Now to do this, we're going to use the id.unique method. While most of the code that we're importing from Appwrite is inside of the Appwrite TS file, we can just do this right inside of our events file where I'm going to also import the ID.
[1:34] Once we have ID imported, we can head back to createEvent and then we're going to head to the end of the function and replace that event ID parameter with id.unique. Of course now that we're creating a document, we ultimately want to pass in that event data so we're going to take that event parameter and we're going to pass it in right at the end of our create function.
[1:55] Now that our function is ready, let's actually start trying to use this. We're going to head to the pages events new file which is going to include a form that's going to capture all the information about our new event. We can find this page inside of the application by heading over to the add event button where we can see that new form.
[2:12] What we want to happen is anytime we fill out this form with all of our information we want to submit it. Then we want to send a request to create that document inside of our collection.
[2:22] Currently on our form, I have an on submit handler so that when that's submitted we're going to trigger custom functionality. Let's get started by importing our createEvent function from at libevents. Ultimately, we're going to be wanting to pass in dynamic data from our form but for now let's just test this out. I'm going to create a new constant of results and I'm going to set that equal to await createEvent.
[2:44] I'm going to create a new object which will include my name, my location, and my date. For the name, let's call this Colby Test 1. For the location I'm going to say Philadelphia PA which isn't super specific like an event but that's good for now.
[2:58] The date's going to be a little bit trickier where we need to pass in a specific format. In particular, we need to pass in a date formatted in the ISO standard. To do this, we can use the date instance and use the toISOString method in order to easily get that set up.
[3:12] Now, I don't currently have a date so I'm just going to say new date which will give me my current date and then I'm going to tag on toISOString.
[3:19] Now as we can see, TypeScript is really not happy with me. I'm currently passing in name, location, and date. If we look at our createEvent function we're currently passing in our live b event type. We can see that we have four required parameters including the id, the name, the location, and the date but we don't want to pass in the id.
[3:37] Now we still want to pass in that live b event but we want to omit some of that information so we're going to omit where we're going to pass in live b event as our first argument but we want to pass in what we want to omit and we're going to omit our dollar sign id. Now as soon as we do that, we can see our createEvent function is now happy again.
[3:56] If we head back to our application, we're going to still have to put a little bit of information into these fields just because they're simply required. If we now click submit, the first thing we're going to notice is that we're actually getting an error and the error is a 401 meaning that we're not currently authorized to perform that action.
[4:13] Now throughout this course, we're going to dig deeper into permissions and how we can configure granular permissions for the different types of people that are going to be accessing our application. This is going to be the first time that we go beyond that read access that we gave to literally anybody that accesses our app.
[4:29] If we look inside of our collection and we head to settings, we can see exactly where we set up those permissions where we have anybody can read our data. Now, we're not yet at a point where we can really restrict our access to somebody who's logged in and we want to still be able to create an event so for now we're going to mark create access to anybody.
[4:48] Let me just reiterate on this. We're currently giving read access to anybody who accesses the application. Because we're later going to be setting up more granular access including restricting this to only logged in users, we want to make sure that anytime we put this out to the world we are able to lock this down and have a little bit more security around our application.
[5:07] For now, we just want to be able to have the ability to create documents as we're working through our application. Let's go ahead and update this permission where now if I trigger a Submit again, this time we don't get any new messages.
[5:18] If we head over to our network tab we can see that if we select this documents request we can see that it was successful and even if we look at the preview we can see all the data on our newly created document.
[5:31] If we even head back inside our dashboard we can see under the events.documents that we now have that Colby test 1.Now, let's set this up to actually pull the data dynamically from the form. Now anytime the submit handler aspired we're going to get this event that includes a target property which is going to be the form that was submitted.
[5:49] E.target is going to be our form where we can use any of fields of our form such as name date or location where we can append any of those to our e.target such as e.target.name where we can get the dot value to get the actual value of that name field. As we can see, TypeScript is not yet happy as it doesn't know that we have name on our target or our form.
[6:10] I'm going to create a new constant called target and I'm going to set that equal to e.target as type of e.target. Then I'm going to add and where I'm going to create a new object. I'm going to list out all my fields including name, location, and date.
[6:23] For all those, I'm going to type them out as an object that includes a property of value which will be a string but now I can start to pass these into my createEvent function. I'm going to replace this with target.name.value. I'm going to do the same thing with my location but make that location.
[6:41] Then we again get to the tricky one of date, but what we can do is we can pass in the string value of date into the new date function so that it reformats it as our date. We have our target date value which will again get translated to an ISO string where I'm going to now add my Colby test 2 and click submit.
[6:58] Where we can see that network request, we can see we get a 201 as well as my new event data. Like before, we can still confirm that we now have that new entry inside of our collection. Now while we're going to handle file uploads in a later lesson, there's one more thing we can do.
[7:12] Whenever we successfully submit a request, we don't want to just stick on this page and act like nothing happened. We want to navigate away. Now this probably depends on the router you're using, but anytime we have a successful event creation, I want to navigate them to that specific event.
[7:25] For the router that we're using which is Wouter, I'm going to import the useLocation hook from Wouter. Where from that useLocation hook I want to grab the navigate function which is going to actually be the second parameter. I'm going to add a comma and then navigate to destructure that.
[7:41] Then after my successful creation, I want to navigate to myEvent where I'm going to dynamically pass in my results.event.$ ID. Now when I submit my test 3, we can see a successful network request and we can see we were immediately navigated over to our new event page for Colby Test 3 at Indy Hall.
[8:00] Now, we can successfully see that we've added that new document. In the next lesson, we're going to learn how we can upload a file to storage so that we can have an image for all of our events.
Member comments are a way for members to communicate, interact, and ask questions about a lesson.
The instructor or someone from the community might respond to your question Here are a few basic guidelines to commenting on egghead.io
Be on-Topic
Comments are for discussing a lesson. If you're having a general issue with the website functionality, please contact us at support@egghead.io.
Avoid meta-discussion
Code Problems?
Should be accompanied by code! Codesandbox or Stackblitz provide a way to share code and discuss it in context
Details and Context
Vague question? Vague answer. Any details and context you can provide will lure more interesting answers!