2.5 PageList Component: Creating Pages
PageList component is responsible for listing all the pages in our wiki. It is also where users will create new pages. In this lesson, we'll start by implementing the page creation feature.
1.Getting Started6 lessons, 27:04
2.Building the Application13 lessons, 1:29:43
3.Conclusion1 lesson, 00:44
2.5 PageList Component: Creating Pages
The next feature that we're going to build is our page list. This will go underneath the logging component inside the app component, and it will display a list of all the pages in the wiki so that the user can choose one to navigate to. We'll also have a text box at the bottom of the list, which will allow the user to create a new page. Actually that create a new page text box is where we're going to start in this lesson. So right now, here in our app component we just have the page list placeholder. Let's go ahead and make that an actual call to a component. Now, of course, the page list component will only allow users to create a new page if they are logged in, and to know whether or not they're logged in, we need the user object. So we'll give this page list component a user object property. At the top here, let's go ahead and import page list from ./PageList. This of course means we need to create that file, so let's create src/components/PageList. Inside this file will start by importing React. And also important our API in the same way we have done previously. Next, of course, we'll export our class. So we'll do export default class pageList extends React.Component. Once again we'll start by setting the state of our class. In this component we do have a text input field that we expect our user to type into. Now, we already had one of those in our logon component. And the way we got the value of that text box is by using a react reference on that input element and then using that to get the dom node, and then we can get the value in that dom node. We're gonna use an alternate method in the page list component so you can see two different ways of doing pretty much the same thing. So for this alternate method, we're gonna start by creating a state property to store the value of that text box. And so we'll say newPageTitle. And this will just start out as an empty string. Then, we can start with a render function. We'll have a div inside this render function, and at the very top of this div, we're going to include a ternary expression. If we have this.props.user, then we want to render our text box. So, we'll create an input with a type of text. We'll give it a class name of u-full-width. We'll set the value of this text box to be whatever our state value currently is. So, this.state.newPageTitle. We'll also give this input a placeholder value of New Page Title. And finally, we'll add an onChange handler to this.update. Now this onChange handler is important. In React, whenever we do something like this with an input field where we set the value to be one of our state properties, if we do not include an onChange handler, then React will make this input read only. If we want to be able to change that value, we need to either use the default value attribute instead of value, or we can include an on change handler. So our on change handler here will be update. And that's all we need for this element right now, so let's close that out. And then we have to include the other portion of our ternary expression, which is, if the user is not logged in. Meaning this .props.user is null, then we will just set this value to null, which means no element at all. All right, so let's create this update function. Since this is an event listener, it will take that event function. And inside this function we'll call this.setState, and we'll update the new page title to whatever the current value of event.target.value is. So whenever a change is made to our text input field here, we will save that change to the new page title state property, and that way new page title will always be whatever value is in that input text field. Now the way we want this input field to work is that the user will type in a new page name, and then they'll hit Enter. And when they hit Enter, we want to go ahead and create that page. So, let's add another event listener to this input element, and that will be for onKeyPress. And we will call this.createPage. So, let's go ahead and create that createPage function. Inside this function, we'll say if event.char code, or the character code for the key that was pressed, does not equal 13. Now 13 is the enter key, or carriage return. So that is the case that we're looking for. So if the event.char code is not 13, well, then we can just return. We want to ignore this character. However, if it is 13, then we'll call API.pages. And remember, this is a reference to our Firebase data store. We have a reference to our pages property within the store, and we can say API.pages and we can use the Firebase method push. And this will add this object to that page's array. Now I'm saying array because we're pushing it in here. However, in terms of actual JSON pages is actually an object, and we'll just have a random unique ID for each one of the elements within there. But the terminology here kind of treats it as an array. So we can say API.pages.push, and we'll push in a new object here, and we'll set the title to be this.state.newPageTitle. And then of course after we create that page, we'll just set a newPageTitle to be an empty string. Now, I want to make sure you understand that when we do api.pages.push, we're actually making a call to the Firebase database and updating that data right away. Now, in the next lesson, when we look at listing the pages, you'll see how we can listen for changes to the database and update our display list of pages when we create a new page. However for now, let's just focus on actually creating a new page. If we come back to the browser and refresh the page, you can see that we actually get a blank page. This is probably because we have an error in our ES6 code and Browserify can't compile it. So let's look at the Browserify output here. It seems that we do have a problem on line two. Oh yeah, I'm saying import star from API from API. If we come back to our PageList.js file here, that should be import star as API, not from API. We can see that once I make those changes, Browserify is now running successfully. So if I head back to the browser and refresh the page again, you can see that underneath our sign out button we have our new page title box. Excellent, now you, of course, remember that we set this up so that if the user was not signed in, they wouldn't be able to create a new page, so let's test that. If I click Sign Out, you can see that not only does the log in component change back to our form, but also the page list component completely disappears. Because right now there's nothing else in there. So our new page title box disappears if the user has signed out. Let me go ahead and sign back in, and now I will create a new page. I'll type in Dogs, and when I hit Enter, you can see that the title we wrote disappears. However since we're not currently displaying a list of pages, there's actually nothing else to see here. However, I have our Firebase Dashboard open here. So let's go ahead and open up the pages object here, and you can see we have a new object within it. And if I open that up, you can see that the title is Dogs. Excellent, so this means we are successfully saving our data back to the database. We can actually see this happen live, if I tear off this tab and move it over here. Then, if I create a new page called cats, you can see right away that a new object is added to the Firebase dashboard. And I can go open that up and you can see that we have the cats property. So now we can successfully create new pages for our application. And the next lesson, we'll look at displaying a list of those pages.