- Read Tutorial
- Watch Guide Video
Right now, we can only log in. So in this guide, we're going to see how we can have our form toggle between logging users in or creating accounts. So let's get started.
If you go to DevCamp Space. And on the Dashboard, you click on the MemiPedia app. And click view data. You'll see that you now have access to a new Endpoint. So this is going to be an Endpoint that allows you to create a user. Now notice that you still have the same type of HTTP verb. This is a post request. So we're going to be sending data and I'm going to show you how we can wrap that data up. Now what I'm going to be showing you, I'm showing you because I created the API, and I know what is required. In an application you'd be building, you'd be going through a little bit more documentation. So you would see some documentation like this, where it says Create user and then it has the Endpoint that you would hit. But it would also provide you with the structure of the data. I'm simply going to show you what that is.
So now that we have that, or we know what it is. It's just MemiPedia underscore users. Then we can go and check out what our users look like right now. As you can see right now, we simply have that one test user.
So let's switch to the code and let's also open up the simulator. I already have it running in the background. So the goal of this guide is I want the ability, when a user clicks register, I want the form to switch with how it sends data. There are a few different of ways of doing that. I'm going to show you a pretty straight forward example. Now if you're building this and it's a big app, and you have a lotta functionality, and you really need to streamline the system, then you might do it in a slightly different way. But my goal is to simply show you how you can have the same exact form perform multiple tasks.
So the first thing that I'm going to do is I'm going to start by extracting out the login functionality that we have right here. So right now, we have our params and we structure how the params look like. And then we're calling that token Endpoint. I'm going to create a new function up here. And this is going to be say const, and I'll just say handle login. It's not going to take in any params and it's going to be a fat arrow function. I'm going to grab all of this content here. At so everything down to the catch block. I'm going to cut it and I'm going to paste it up here, in the handle login function.
AuthScreen.tsx
const handleLogin = () => { const params = { auth: { email: email, password: password } }; API.post("memipedia_user_token", params) .then(response => { if (response.data.jwt) { props.navigation.navigate("Feed"); } else { alert( "It looks like you typed in the wrong email or password, please try again" ); } setIsSubmitting(false); }) .catch(error => { setIsSubmitting(false); alert( "It looks like you typed in the wrong email or password, please try again" ); }); };
Now I'm going to call this, down here, just to make sure everything is still working properly. So inside of handle submit, I'm now going to say, we're calling this handle login function. I'll hit save, and now let me test this out.
AuthScreen.tsx
const handleSubmit = () => { setIsSubmitting(true); handleLogin(); };
So I'll go, my username was reactnative@devcamp.com and my password was ASDF ASDF. Now if I click Login, everything still works properly. Now I'm also hit command R to refresh, to take me back because one thing that, as you go through this, you're going to see the simulator. Not only is the simulator changed in how it works, but Expo's continually improving how it works. And one thing that's happened, just while this course has been filmed, is they've implemented a really nice hot loading functionality. And you're going to see it, as we go through the course. But just to give you a little bit of a sneak preview of it. When I started writing Expo apps, anytime I would hit save, it would reload the entire system. So if I was on some screen, five screens deep, it would actually take me all the way back to the initial screen. And I'd have to click all the way through. And that definitely was a little bit time consuming. So what they've implemented is now, it recognizes the components that are being used. And it only updates those elements, so it makes it much faster. And so if you have to get back to the screen, like we did right there, if you hit command R, that should take you back to it.
Okay so we know that this function's working now. So what I want to implement is the function for creating the users. So for that, I'm going to come up here and let's create a new function. I'm going to say const, and I'll say handle registration. It also's going to be a fat arrow function that doesn't take in any arguments. And I'm going to be able to really replicate a lot of the code we have up here. It's going to be different, but there is going to be some similarities. So I'm just going to paste this in and let's go up and see what has to change. So the first thing that has to change is our params. The token Endpoint expects an object called auth. In the registration Endpoint, it expects an actual user object to be passed in. So that's going to be the first change. So and that's part of the reason why I had to move this params into both functions, because it's going to create a different type of object.
So that's a first thing. Next thing is going to be this post request. So here it's simply, if you go back and look at DevCamp Space, it is MemiPedia underscore users. So that's the next thing. So that's a different Endpoint that it's hitting. And then next, we have our response. So before, remember we were looking for a jot for that JWT token. Here we're actually looking for an object that's going to be returned to us, called MemiPedia user.
And once again, if you're wondering, how in the world would I know that if I didn't just tell you? The API documentation. So whenever you are building out an app like this, and you're connecting to some other service. Whether you're working for a company, and you have an internal API. Or you're working, and say you're building an integration with Facebook or some other authentication system, they're going to provide that documentation. What they'll do, the documentation will give you that Endpoint. It'll give you the HTTP verb. It'll give you the structure. So all the things we just implemented, it tells you. And it typically has code examples.
And then lastly, it says, this is the data that's going to be returned. So that is what you have there. We want the same thing to happen. As soon as we are sure that a user's been created, then we want to navigate to the feed screen. So everything there is the same.
Now the alert is going to be a little bit different. So here, let's streamline this first. Let's just make it really dead simple. And then in one of the next guides, we're going to see how we can give some really helpful information to our users. And so I'm going to say alert, and I'll just say error creating user account. And then I'm going to copy this alert, and move this down here into our error. And then I'm going to also grab this, set is submitting. We want to make sure that that gets turned off. So when the alert is shown, so if a user's not created, we also want to set is submitting to false. And I'm going to check up here. It looks like we didn't, oh okay we did it down here. Let's verify, okay I would've done that twice. So let's not do that. That's my mistake.
AuthScreen.tsx
const handleRegistration = () => { const params = { user: { email: email, password: password } }; API.post("memipedia_users", params) .then(response => { if (response.data.memipedia_user) { props.navigation.navigate("Feed"); } else { alert("Error creating user account"); } setIsSubmitting(false); }) .catch(error => { setIsSubmitting(false); alert("Error creating user account"); }); }; const handleSubmit = () => { setIsSubmitting(true); if (formToShow === "LOGIN") { handleLogin(); } else { handleRegistration(); } };
Okay so we're, just so we can walk through the flow. We're calling our new Endpoint. We're passing in params, which is going to be a slightly different type of object. This is one where we wrap it up in a user object. Then we're looking for, and we're waiting for a response that says, I have this user for you and it uses this naming structure. If that's the case, we're going to redirect the user to the feed. And then if not, we're going to show an error. And if we just get a regular server error, that's where, and if you want to know what the key difference between these two, because that's a good thing to think about, this is what you would see if you sent, say a duplicate user. And when we walk through how the errors work, then you're going to see how what happens here. What happens down in the catch block, this is more of what would happen if you called a completely wrong URL. So you need to make sure you're listening for those errors, because they there's a server error. Or you, like I said, you're calling the wrong Endpoint. Then it's going to fall down in this catch block.
So I'm going to hit save here. And this is all good, but now we need to figure out how to call this. So in our handle submit function, what I'm going to do is create two divergent paths here. I'm going to say, if, and the piece a state we're using here is form to show. If this form to show equals login, then I want to use our handle login function. Else, then I want to do the handle registration function. And make sure you actually call these, so you can't just call the name, you also have to invoke a function by using the parens after it.
AuthScreen.tsx
const handleSubmit = () => { setIsSubmitting(true); if (formToShow === "LOGIN") { handleLogin(); } else { handleRegistration(); } };
So I'm going to hit save here. And let's come back and let's also open up the terminal. And let's use add some debugging. So here inside of our then for our handle registration, let's just use a console log statement. So console log response for creating user, and I'll call response dot data. Hit save. So now what's going to happen is as long as we're creating an account, and we didn't fall into this error block, then it's going to send us and print out this data to the terminal.
AuthScreen.tsx
console.log("Res for creating user", response.data);
So open go to the terminal and then, I'm going to clear this so it's right at the top. You could also use your browser. And let's come to our page, and I'm going to click register. I'm going to create a new user here. So let's just say, video register, there you go, videoregistrationuser@devcamp.com and I'll give a password. So now if I click on register, it looks like everything worked. Don't worry about these warnings. These are something that just were released in the latest version of the Expo SDK. So don't worry about that for right now. We'll take care of those later.
But it looks like everything worked. Let's scroll up and you can see, we got our console log response. It says, Res for creating user. We got some metadata that the API returns, but then down below here, we got that email. We got the email for what we created, along with the ID. Everything is working really nicely there.
Let's come back to DevCamp Space and go to Users. And let's see what we have. And there you go. That user was created.
So we now have the ability to switch between a login form and a registration form. And also call different APIs. So even though it looks really nice and simple to the user, we're actually creating this divergent behavior, and this dynamic behavior, by being able to toggle between different state elements.
So really nice job, if you went through that. If any of that was kinda confusing or just, you don't really understand it yet, I recommend for you to go through this code again. And maybe even remove all the code you just typed. Go through, type it again. And see everything that you typed out, so that it really starts to make sense, because we're going to be able to perform these kinds of tasks quite a bit, throughout the rest of the course. So I want to make sure that this is making sense to you.
So now with all of this in place, in the next guide we're going to see how we can handle what happens when users create errors. Or errors occur when they're using the application.