7 days of WordPress plugins, themes & templates - for free!* Unlimited asset downloads! Start 7-Day Free Trial

Next lesson playing in 5 seconds

  • Overview
  • Transcript

4.9 Creating the User Store

So far our application has been fairly focused on a single user. We've created the means for a single user to sign up and log in, and make a new chirp, and see a list of chirps. However, now we want to zoom out a little bit, because of course there's no point in having a chirp application if you can only see your own chirps, right? So we want to allow a logged in user to interact with other users. In the context of our application that means being able to view a list of users, being able to view a user's profile and also being able to follow and un-follow users. So the first thing we'll need to power all of that user UI would be a user store. So I'm going to create a new file in our source/stores directory, and this is going to be users.js, and of course this is the store where we will keep track of our list of users. We'll start by creating our UserStore variable, which is also our module.exports variable. We'll create our store by first requiring our store constructor. So that's the store file in the same directory, and then we can call extend, and we'll pass this extend on object. Now you may recall from when we created the chirp store, that the primary thing we need to do in here is the init function. And if we look back at the init function in our ChirpStore as an example, you can see that the purpose of our init function here is to bind our store to some of these actions in our application. So that we can update the store when those actions happen. So we're going to want to do that in the UserStore. The first and most obvious one would be this.bind(constants.GOT_USERS). This will be the event that happens when we fetch a list of users from the server and we want to set these in the store. So we'll say this.set very similar to what we did before, GOT_CHIRPS in the ChirpStore. Now of course we haven't pulled in this set of constants yet. So let's add a constants variable up here at the top, and we can get this by requiring the constants module. Now the UserStore will be more than just a list of available users. We also want to use this store to keep track of the currently logged in user. Now you might recall, if I open up our index.ejs view, we have the currently logged in user's information here as a global variable, all uppercase USER. So what we're gonna do from within our UserStore here, is actually create a currentUser property on our UserStore. And we'll just give this the default value of that user that we created when we rendered our template. And this will work for many situations. However, there is one case where we're going to need to update the current user object. And this happens when a user follows or unfollows another user. Eventually, some of our views are gonna have a follow and unfollow button, and when this happens, of course, a request will be sent to the server letting the server know that the current user wants to follow a new user. That, of course, will be the follow action. However, when the server returns and says that we successfully followed that user, the followed action will occur, and we want to bind our UserStore to that followed action. So we can say this.bind to constants.FOLLOWED, and when this happens we want to call this.updateUser. Now, we don't have an updateUser function yet so let's go ahead and create that. So we can say updateUser, and the data that will come back from the server, we'll get as a parameter to updateUser. This data is actually just going to be the same data that was passed into our index.ejs template. So what we can do here is say this.currentUser equals data. Now a similar thing will happen when we decide to unfollow a user. So let me just duplicate the binding here, and when we have the UNFOLLOWED action, we'll do the same thing. We will update the user by calling our updateUser function, and this will keep our currentUser property up to date. Now this is our entire UserStore, it doesn't take a whole lot of code to manage our list of users, but what we should also do before this lesson is over is update our api.js file. Currently you can see we have the fetchChirps method here, which we use to initially get a list of all the chirps in the system. Well, we should also have a fetchUsers method here. And this will fetch all the users when our page initially loads, so that we can display a list of users to the currently logged in user. So we can do something really similar to what we did here in fetchChirps. We can say get api/users. And then when that returns we can call actions.getUsers, and of course we'll bind that to actions. Now, if we come over to our main.js file, here where we call API.fetchChirps we can also call API.fetchUsers, and this will load up the users into our front end store. Now I still have gulp and our web server running. So if we come back to the browser and refresh the page, you can see we have a couple of errors. Now the first one is not the error I was expecting. It says, action is not defined, and this is on API line ten, if we come back to the api.js file. Okay, it looks like I said action instead of actions, and I'm also noticing here I said getUsers instead of gotUsers. So the callback we want to call here is actions.gotUsers and then we're binding that back to the actions object. Okay, with that updated, we can refresh the page again. And you can see at least the error we're getting right now does not actually break our page. So we can still see the content that we've created so far. However, we have a different, however, there is still an error. First of all, notice that we only have one action being logged in our console here and that's the GOT_CHIRPS action, and then that's from the code that we have previously written. But what we were expecting to see based on this lesson, is another object with an action type of GOT_USERS. However instead we have this error, we have an unexpected token less than sign. So the problem is if we come here to the network tab and look at our request to /api/users, you can see right here the request went to ApiUsers and the response was our index.html page. Now if you recall what we did on the server side this should make perfect sense. Here in api.js we're making a fetch to /api/users. However, we never actually made an API that returned a list of users. This is non existent on the server. So we have to go ahead and create that. So I'm going to open up the login.js file, and right down at the bottom, I'm going to add a new route to our router object, and this is gonna be really, really simple. It will be router.get, and we want to get /api/routes, and what we wanna send back here is an array of all the users that have created accounts in our application. Now, if we scroll up to the top here, you can see that we have our users collection as part of our locallyDB database. So we can use this users collection, here, and just call a toArray method to get an array of all the users in the collection. So we can just say users.toArray, and then we can call map, and we can map these users over the makeUserSafe function that we already created. This way, we can only include the properties that we want the client to be able to see. Finally, let's wrap all of this in a call to response.json and this will successfully send our users back to the server. Of course, there's this one glaring mistake which you probably caught already and that is, it should not be /api/routes. It should be /api/users, sorry about that. All right, now since we made a change to the server, I'll have to come back to the terminal and restart the server. Back in the browser, this means we'll have to log in again, and when we do that, notice that we have our second action being logged to the console. We have an action with the type of GOT_USERS, and we have an array with just a single user in it, and I'm sure you can guess that is the currently logged in user, because that's the only user in our application so far. However, this is a good start to our users functionality.

Back to the top