Adding User Slice

In this lesson, we're going to add user slice

Project Source Code

Get the project source code below, and follow along with the lesson material.

Download Project Source Code

To set up the project on your local machine, please follow the directions provided in the README.md file. If you run into any issues with running the project source code, then feel free to reach out to the author in the course's Discord channel.

This lesson preview is part of the The newline Guide to Fullstack ASP.NET Core and React course and can be unlocked immediately with a single-time purchase. Already have access to this course? Log in here.

This video is available to students only
Unlock This Course

Get unlimited access to The newline Guide to Fullstack ASP.NET Core and React with a single-time purchase.

Thumbnail for the \newline course The newline Guide to Fullstack ASP.NET Core and React
  • [00:00 - 00:16] Now that our login function is working fine and we are able to make a request and receive a response, we need to store the user's data so that they stay logged in. Since we are using Redux toolkit, we need to create a new slice and we will call it user slice.

    [00:17 - 00:25] We also need to create a new model for the users. So inside user.ts let's create another model for the user.

    [00:26 - 00:46] So on top. Let's write export interface and user and for now we will just have email which will be of type string and a token of type string.

    [00:47 - 01:06] Because for now this is what we are returning back to the user and this is what we will store inside Redux. Now inside Redux, let's make a new slice for the user.

    [01:07 - 01:19] Let's start with the interface and this interface is for the user state. This user state will have only a user.

    [01:20 - 01:28] So let me write user. This will have a type user which we just created or it could be null.

    [01:29 - 01:35] So if the user is authenticated, it will be type user. If it's not, it will be null.

    [01:36 - 01:47] Now we can create the initial state which will be of type user. So let's say const initial state and this will have a type user state.

    [01:48 - 01:59] And initial state of the user will be null. Then we can create a user slice.

    [02:00 - 02:16] So we will export const. Let's simply call it user slice which will be equal to the create slice we have seen it a lot of times now, create slice let's import it.

    [02:17 - 02:29] It will take a name and name for this can simply be user. And it also takes initial state and reduces.

    [02:30 - 02:34] Let's keep it empty for now. We can now register this inside our store.

    [02:35 - 02:42] So what we'll do is inside our configure store. Let's also mention user.

    [02:43 - 02:54] This will be equal to user slice dot producer. Now coming back to the user slice, let's write our async functions now.

    [02:55 - 03:00] So let's write it here. So let's start with the sign in user function.

    [03:01 - 03:09] Like always we will write export const sign in. Let's make it capital sign in user.

    [03:10 - 03:15] This will be create async function. Create async.

    [03:16 - 03:20] Thunk. Now from this function, we will return the user.

    [03:21 - 03:34] So inside angle brackets, I will write user and as a parameter, we need to pass the data which will be of type login. So if you remember, a login has email and password.

    [03:35 - 03:40] So this is what we need to pass as parameters. So I will write login.

    [03:41 - 03:46] That's imported using the users. Now inside the parentheses, we need to write the prefix.

    [03:47 - 03:56] So let's call it user slash sign in. And after that, we will write our async function.

    [03:57 - 04:01] So let me write async. Inside this function, we will pass two parameters.

    [04:02 - 04:13] The first one is data, which is the login data. And the second one will be thunk API.

    [04:14 - 04:24] Now let's write our function. And since it's an asynchronous function, we will wrap it inside try catch block .

    [04:25 - 04:29] So the catch will have an error. Let's give it type any.

    [04:30 - 04:48] And if it's an error, we can simply return thunk API dot reject with value and we will return the error, which will be this error object. And inside the try block, we will store the response inside the user constant.

    [04:49 - 04:54] So let me write constant user. And here I will make the API call.

    [04:55 - 05:07] So I will write a weight agent, let's import agent dot users dot login. And this will take data, which is of type login.

    [05:08 - 05:16] After this, we need to store the user object somewhere. Even if we store it inside Redux, it will be gone once the user refreshes the application.

    [05:17 - 05:24] And we don't want to lose the user token when they refresh it for some reason. So what we can do is we can store it inside local storage.

    [05:25 - 05:45] We already stored client ID inside a cookie, but in case of the user token using local storage is a better solution. So below the API call, we can use local storage dot set item and the key for this local storage will be user and the value will be user, but we can't pass the user like this.

    [05:46 - 05:54] So we'll have to stringify it. So we will use Jason dot stringify and we will pass the user.

    [05:55 - 06:04] Finally, we can return the user. Now we see the error because the promise is uncertain for now and it can't say for sure if it's going to return a user.

    [06:05 - 06:18] So to resolve this, we can go back to the agent file and make them a show that we will return a user from this call. So let's write user and the same goes for the register property.

    [06:19 - 06:28] So I will simply copy it and paste it because from both of these API calls, we are returning a user. Now this will take care of this error.

    [06:29 - 06:34] Now our login and register user functions are not much different. Both of them return a user.

    [06:35 - 06:43] So what we can do is simply copy it and paste it one more time. Now we can name it register user.

    [06:44 - 07:00] So register user and change the type to register and we will import it from models user. Also, the prefix name should be user slash register.

    [07:01 - 07:10] And let's change the API call from user slogan to users dot register. Rest everything can stay the same.

    [07:11 - 07:20] And like always, we can use the extra reduces for setting the user state. So here, let me write extra reduces.

    [07:21 - 07:27] And like always, we will have access to the builder. So let me write builder.

    [07:28 - 07:37] And now I can run this function. This time we are not going to use the builder dot add because both of our functions return a user.

    [07:38 - 07:45] And we don't want to duplicate the logic. So rather than using builder dot add, we can use builder dot add, match up.

    [07:46 - 07:52] So builder dot add, match up. And here we can use multiple functions.

    [07:53 - 08:01] If any of them is called, we can save response from any one of them. And as a first parameter, it takes is any of function.

    [08:02 - 08:28] So let me enclose it in brackets and below, let me write is any of this will take the two conditions and we can write sign in user dot fulfilled and register user dot fulfilled. And as a second parameter, it accepts a function with state and action.

    [08:29 - 08:40] So here, let's write state and action. Here, we can set the user to be action dot payload.

    [08:41 - 08:52] So what I'll do is write state dot user is equal to action dot payload. We can copy it one more time for the rejected state.

    [08:53 - 09:00] So let's copy it and paste it. This time, it should be rejected rather than fulfilled.

    [09:01 - 09:06] So I'll select it and write rejected. And inside, we don't want to set any state.

    [09:07 - 09:14] We can simply throw the payload because it's going to be an error. So we are simply throwing action dot payload.

    [09:15 - 09:22] Our user slice is now ready. Now we can go to the sign in page so that we can take the API calls logic away from it.

    [09:23 - 09:34] So let's go to the sign in page. And where we are making the API call here and for making that API call from the user slice, we need dispatch.

    [09:35 - 09:59] So what we can do is on top, I can write const dispatch, which will be equal to use dispatch. Now we can take away that logic and simply dispatch the sign in user function that we created inside user slice, which will take the values.

    [10:00 - 10:08] And these values are nothing but our email and the password. And now after we submit this function, first of all, let's make it asynchronous .

    [10:09 - 10:16] So let me use await. And since it can fail, we can also wrap it inside the try catch block.

    [10:17 - 10:36] So what I'll do is now write try and catch with an error. Inside the try block, I can use this logic and paste it.

    [10:37 - 10:44] Now we also want to clear the fields after we submit the form. So what we can do is create a new function and let's call it reset form.

    [10:45 - 10:53] So let's make it here. Let's call it const reset form.

    [10:54 - 10:59] Inside we can set the values to empty. So what I'll do is use set values.

    [11:00 - 11:12] Let's start with dot dot dot values, which are all the values. And after that, I'll put email and make it empty and same goes for the password .

    [11:13 - 11:28] Let's make it empty as well. And since we are using and D here, we will have to remove the reference from the and deform as well for which what we need to do is we need to de-structure the form from the form that we have already imported from and D.

    [11:29 - 11:46] So what we can do is here, let's de-structure the form from form dot use form. And inside the function, we just need to use form dot reset fields.

    [11:47 - 11:58] It won't work until we pass this form reference to our actual form. So what we can do is in this form, we can use form is equal to form.

    [11:59 - 12:07] Now we have passed the reference. And now when we use form dot reset fields, it will reset all the reference that it has.

    [12:08 - 12:17] Now inside the dry catch block, after we submit this, we want to reset form. And also if it fails, we want to reset it as well.

    [12:18 - 12:35] But once it fails, we can show a notification to the user and that notification is provided from and D. So what I can do is use notification from and D. And since we are going to show an error, we will write notification dot error. And inside, we can use a message.

    [12:36 - 12:48] So let's write message. And here we can write, please check your email or password.

    [12:49 - 13:01] And finally, we can use the reset form function here as well, because we want to clear the fields as soon as the user submits the form. And now we can simply remove the agent call because we don't need it anymore.

    [13:02 - 13:10] And as you know, the sign in component and register component are almost the same. So we can use the same logic for register component as well.

    [13:11 - 13:20] So let's close this and this and open the register component. And now we are making the submit user call.

    [13:21 - 13:28] We just want to get rid of this. And let's get rid of everything.

    [13:29 - 13:41] And let's create a reference of dispatch, which will be equal to use dispatch. We also need a form reference.

    [13:42 - 13:56] So let's write const form is equal to form dot use form. And like always, we can wrap it inside a try catch block.

    [13:57 - 14:25] So let's write try and catch error type any inside the try block. I will cut this logic and restate and inside we want to dispatch the register functions values dispatch and register user, which will take the values.

    [14:26 - 14:33] And we also need the reset form function. So what we can do is simply copy it from here because it is same.

    [14:34 - 14:45] And here we can paste it. And after you make the register user function, we can call it.

    [14:46 - 14:49] And also we can use the notification. So the logic is same.

    [14:50 - 14:59] Let's simply copy it, paste it. Now let's import notification.

    [15:00 - 15:10] Here the message can be please check your credentials. And the form should be restructured.

    [15:11 - 15:16] So this will take care of the error. Let's also remove the agent call.

    [15:17 - 15:29] And one more thing inside the reset form function, we also need to pass the username and make it an empty string. Now we can open the browser to check if the functionality is working as expected.

    [15:30 - 15:43] Let's use the wrong credentials first. So we'll say student at the rate student dot com and we can use any password.

    [15:44 - 15:52] As you can see, we see a notification which says, please check your email or password. And also the fields are now empty.

    [15:53 - 15:59] Let's try the same with the register component. So what we'll do is we'll use the previously used credentials.

    [16:00 - 16:16] So I can use student and here I can use student at the rate test.com and can use the same password. Now if you run it, it's not working as expected.

    [16:17 - 16:28] Let's see if we have passed the forms credentials. So inside form and yes, we forgot to pass the form reference.

    [16:29 - 16:34] And since we are here, let's check if we have done everything correctly. And yeah, I found one more thing.

    [16:35 - 16:40] We should await this dispatch call. Now I think it looks fine.

    [16:41 - 16:53] Let's go back to the browser and now let's use the same credentials. And we can use any password.

    [16:54 - 17:04] Now if I click submit, we see another notification error which says, please check your credentials. And also the fields are now clear.

    [17:05 - 17:11] This means the API requests are now working fine. Also the error notifications work fine.

    [17:12 - 17:18] Now let's show the user logged in in the navigation bar rather than showing login all the time. So let's do it in the next lesson.